2014-02-19 446 views
5

我有一個用於加密的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,但它不會給我一個十六進制加密字符串作爲輸出 –

回答

9

試試這個:

#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

這是一個加密++代碼 –

6
+0

我試過使用Crypto ++,但沒有運氣。我只需要將java方法轉換爲C++ –

+2

爲什麼Crypto ++沒有運氣? – Corvusoft

+0

我嘗試了您提供的鏈接。它給了我加密的字符串,但Java和C++的輸出永遠不匹配。我需要提供一個十六進制密鑰,然後我的加密的字符串最終應該是十六進制的。我不想用鹽 –