Java实现的C ++加密解密函数(Cryptix工具箱)

时间:2013-08-06 10:25:06

标签: java c++ encryption

您好我正在尝试加密和解密2个系统中使用的数据(一个是C ++和另一个Java)我从代码项目中找到了一个Demo项目:Encryption这是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;
    }
}

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

enter image description here

数据经过加密端解密..

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

提前致谢。

2 个答案:

答案 0 :(得分:2)

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

请注意,您的示例只会加密和解密单个块(16个字节)。如果您需要更多内容,则需要使用CRijndael EncryptDecrypt方法(而不是EncryptBlockDecryptBlock)。下面的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。

答案 1 :(得分:1)

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