0

嗨,我正在尝试加密和解密 2 个系统中使用的数据(一个是 C++,另一个是 Java)我从代码项目中找到了一个演示项目:加密 这是 c++ 加密解密函数,它在我实现代码时工作使用功能:

void main()
{
    try
    {
        CRijndael oRijndael;
        oRijndael.MakeKey("abcdefghabcdefgh", "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 16);
        char szDataIn[] = "Password12345678";

        char szDataOut[17] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";

        oRijndael.EncryptBlock(szDataIn, szDataOut);

        cout << "[" << szDataIn << "]" << endl;
        cout << "[" << szDataOut << "]" << endl;
        memset(szDataIn, 0, 16);

        oRijndael.DecryptBlock(szDataOut, szDataIn);
        cout << "[" <<  szDataIn << "]"  << endl;

    }
    catch(exception& roException)
    {
        cout << roException.what() << endl;
    }
}

这给了我控制台中的以下输出:

在此处输入图像描述

数据加密结束解密..

任何人都可以帮助我或指出正确的方向,让 Java 实现加密和解密相同的数据,得到相同的结果(用 C++ 加密,然后用 Java 解密,然后用 Java 加密,用 C++ 解密)?在帖子中他们谈论 Cryptix 工具包?

提前致谢。

4

2 回答 2

2

此 Java 代码将加密/解密并产生与您的示例编码为十六进制相同的输出。输出看起来是相同的(并且应该是相同的),但要 100% 确定您需要在 C++ 示例中对输出进行十六进制编码。

请注意,您的示例只会加密和解密单个块(16 个字节)。如果您想要更多,则需要使用CRijndael EncryptandDecrypt方法(而不是EncryptBlockand DecryptBlock)。下面的 Java 代码适用于两者,无需修改。

public static void main(String[] args) throws DecoderException, InvalidKeyException,
        NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException {
    //Hex encoding/decoding done with Apache Codec
    byte[] key = "abcdefghabcdefgh".getBytes();
    String text = "Password12345678";

    byte[] encrypted = encrypt(key, text.getBytes());
    byte[] decrypted = decrypt(key, encrypted);

    System.out.println("Text: " + text);
    System.out.println("Encrypted: " + Hex.encodeHexString(encrypted));
    System.out.println("Decrypted: " + new String(decrypted));
}

public static byte[] encrypt(byte[] key, byte[] unencrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Set up the cipher and encrypt
    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"));
    byte[] encrypted = cipher.doFinal(unencrypted);

    return encrypted;
    }

public static byte[] decrypt(byte[] key, byte[] encrypted) throws NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException{
    //Decrypt the encrypted text
    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"));
    byte[] decrypted = cipher.doFinal(encrypted);

    return decrypted;
}

输出

Text: Password12345678
Encrypted: 6c7d800fad2bb8593db92847bbbdbeff
Decrypted: Password12345678

不过,给你一个大警告,这种加密(ECB,无填充)非常不安全,你永远不应该在真实系统中使用它。您真的应该使用带有初始化向量和 PKCS5 填充的 CBC。

于 2013-08-06T13:13:37.800 回答
1

确保不要直接从 char 数组中导出加密数据。使用固定大小的输出或使用字节缓冲区。这是强制性的,因为在加密字符串中,您可能有可以解释为控制字符 fe\0标记的字节组合。如果是这样,使用打印输出到文件...<< szDataOut;可能会损坏您的加密字符串,并且无法被第二个应用程序完全读取(无论是 java 还是 c++)。

于 2013-08-06T10:40:32.773 回答