C++和Qt 5中的AES 256加密

问题描述:

我有一个用于加密的Java代码,如下所示!C++和Qt 5中的AES 256加密

private static byte[] encrypt(byte[] raw, byte[] clear) throws 
    Exception { 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    Cipher cipher = null; 

    if(isIVUsedForCrypto) { 
     cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(IV)); 
    } 
    else 
    { 
     cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
    } 
    byte[] encrypted = cipher.doFinal(clear); 
    return encrypted; 
} 

public static byte[] toByte(String hexString) { 

    int len = hexString.length()/2; 
    byte[] result = new byte[len]; 
    try{ 
    for (int i = 0; i < len; i++) { 
     result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2),16).byteValue(); 
    } 
    }catch (Exception e) { 

    } 
    return result; 
} 

public static String toHex(byte[] buf) { 
    if (buf == null) 
     return ""; 
    StringBuffer result = new StringBuffer(2*buf.length); 
    for (int i = 0; i < buf.length; i++) { 
     appendHex(result, buf[i]); 
    } 
    return result.toString(); 
} 
private final static String HEX = "ABCDEF"; 
private static void appendHex(StringBuffer sb, byte b) { 
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f)); 
} 

从Java主要方法:

byte[] result = encrypt(toByte(rawKey), plaintext.getBytes()); 

我需要编写为上述方法中的C++当量(在Java)。我没有意识到Cryptography的C++类,并希望有人请提供一个显示相同的例子。

在此先感谢

编辑

我的原始密钥是在像十六进制 - > 729308A8E815F6A46EB3A8AE6D5463CA7B64A0E2E11BC26A68106FC7697E727E

和我最后的加密的密码 - > 812DCE870D82E93DB62CDA66AAF37FB2

此作品在Java但我需要一个类似的解决方案C++

+0

“我不知道Cryptography的C++类”。根据下面的注释判断,您*至少知道一个库。你有没有调查过为什么它看起来不会做你想要的?你有什么其他的图书馆尝试过?是否有某些原因必须是C++,而不是简单的OpenSSL api栈?或者是一个工作完成的薄膜包装? – WhozCraig

+0

我曾尝试过Botan,但它不会给我一个十六进制加密字符串作为输出 –

试试这个:

#include <crypto++/aes.h> 
#include <crypto++/modes.h> 
#include <crypto++/filters.h> 
#include <crypto++/hex.h> 
#include <crypto++/sha.h> 
#include <crypto++/md5.h> 

QString Foo::decrypt(const QString &password) 
{ 
    string plain; 
    string encrypted = password.toStdString(); 
    // Hex decode symmetric key: 
    HexDecoder decoder; 
    decoder.Put((byte *)PRIVATE_KEY,32*2); 
    decoder.MessageEnd(); 
    word64 size = decoder.MaxRetrievable(); 
    char *decodedKey = new char[size]; 
    decoder.Get((byte *)decodedKey, size); 
    // Generate Cipher, Key, and CBC 
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ]; 
    StringSource(reinterpret_cast<const char *>(decodedKey), true, 
        new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH))); 
    memset(iv, 0x00, AES::BLOCKSIZE); 
    try { 
     CBC_Mode<AES>::Decryption Decryptor 
     (key, sizeof(key), iv); 
     StringSource(encrypted, true, 
         new HexDecoder(new StreamTransformationFilter(Decryptor, 
            new StringSink(plain)))); 
    } 
    catch (Exception &e) { // ... 
    } 
    catch (...) { // ... 
    } 
    return QString::fromStdString(plain); 
} 

QString Foo::encrypt(const QString &password) 
{ 
    string plain = password.toStdString(); 
    string ciphertext; 
    // Hex decode symmetric key: 
    HexDecoder decoder; 
    decoder.Put((byte *)PRIVATE_KEY, 32*2); 
    decoder.MessageEnd(); 
    word64 size = decoder.MaxRetrievable(); 
    char *decodedKey = new char[size]; 
    decoder.Get((byte *)decodedKey, size); 
    // Generate Cipher, Key, and CBC 
    byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ]; 
    StringSource(reinterpret_cast<const char *>(decodedKey), true, 
        new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH))); 
    memset(iv, 0x00, AES::BLOCKSIZE); 
    CBC_Mode<AES>::Encryption Encryptor(key, sizeof(key), iv); 
    StringSource(plain, true, new StreamTransformationFilter(Encryptor, 
        new HexEncoder(new StringSink(ciphertext)))); 
    return QString::fromStdString(ciphertext); 
} 

更新:

使用上面的代码如下:

//... 
#define PRIVATE_KEY "729308A8E815F6A46EB3A8AE6D5463CA7B64A0E2E11BC26A68106FC7697E727E37011" 
QString encrypted = Foo::encryptPassword("test"); 
// use encrypted 

我个人不喜欢在源代码中显示私钥。所以我会通过命令行将它传递给编译器:

g++ -DPRIVATE_KEY \"\"\"123...\"\"\" ... 

其中PRIVATE_KEY是纯文本中的私钥。如果你有十六进制编码的密钥,只需删除Hex decode symmetric key步骤。

+0

是的会尝试让你现在知道...谢谢你的例子 –

+0

上面的代码使用任何库吗?或者我可以将它与Botan一起使用吗? –

+0

这是一个加密++代码 –

+0

我试过使用Crypto ++,但没有运气。我只需要将java方法转换为C++ –

+2

为什么Crypto ++没有运气? – Corvusoft

+0

我尝试了您提供的链接。它给了我加密的字符串,但Java和C++的输出永远不匹配。我需要提供一个十六进制密钥,然后我的加密的字符串最终应该是十六进制的。我不想用盐 –