8

I have a Java code for encryption in place as follows!

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 = "0123456789ABCDEF";  
private static void appendHex(StringBuffer sb, byte b) {  
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));  
}  

From Java main method:

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

I need to write the C++ equivalent for the above methods (in java). I am not aware of the C++ classes for Cryptography and would like someone to please provide an example showing the same.

Thanks in advance

EDIT

My raw key would be in hexadecimal like -> 729308A8E815F6A46EB3A8AE6D5463CA7B64A0E2E11BC26A68106FC7697E727E

and my final encrypted password is --> 812DCE870D82E93DB62CDA66AAF37FB2

This works in Java but I need a similar solution for C++

Parth Doshi
  • 4,200
  • 15
  • 79
  • 129
  • "I am not aware of the C++ classes for Cryptography" .. judging from the comment left below, you *are* aware of at least one library. Have you investigated why it seemingly doesn't do what you're looking for? What other libraries have you tried? Is there some reason it has to be C++ and couldn't instead simple be an OpenSSL api-stack? Or a get-the-job-done thin wrap? – WhozCraig Feb 19 '14 at 15:43
  • I have tried Botan but that doesnt give me an hexadecimal encrypted string as output – Parth Doshi Feb 19 '14 at 15:43

1 Answers1

14

Try this:

#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);
}

Update:

Use above code as follows:

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

Personally I don't like to reveal private key in source code. So I'll pass it to compiler in command line:

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

Where PRIVATE_KEY is your private key in plain text. If you have the key in HEX encode, just remove Hex decode symmetric key step.

sorush-r
  • 10,490
  • 17
  • 89
  • 173
  • yes will try and let u know now...thanks for the example – Parth Doshi Feb 19 '14 at 16:06
  • does the above code use any library? or can I use it with Botan? – Parth Doshi Feb 19 '14 at 16:08
  • Ok fine. At present I need to encrypt only using AES-256 algorithm. will it work if I give a raw key as hexadecimal? Is there any line of code i need to remove from encrypt method. Check the edit in question – Parth Doshi Feb 19 '14 at 16:21
  • If you are planning to give the key as HEX-encoded string, remove lines between two comments (`Hex decode symmetric key` and next comment) – sorush-r Feb 19 '14 at 16:25
  • ok fine I got it and is it for AES 256 ? I do not want to use any salt – Parth Doshi Feb 19 '14 at 16:28
  • This algorithm uses `AES::MAX_KEYLENGTH` as key length which is 32 bytes in length in my compile of the library. So yes, it's AES-256 – sorush-r Feb 19 '14 at 16:32
  • except QString rest other code is pure C++ right? I mean QString belongs to Qt only. Is there any difference between QString and string – Parth Doshi Feb 19 '14 at 16:33
  • QString belongs to Qt, rest of code is plain C++ plus some convertion between `std::string` and `QString`. `QString` is basically an extended cross-platform string class implementation. – sorush-r Feb 19 '14 at 16:37
  • @ParthDoshi Depends on your system. In my Ubuntu they're `in /usr/include/crypto++` – sorush-r Feb 19 '14 at 21:05
  • My password is let's suppose "test" and key is something like "729308A8E815F6A46EB3A8AE6D5463CA7B64A0E2E11BC26A68106FC7697E727E37011" then How do i write it in c++ . I am not understanding since i m new to C++ – Parth Doshi Feb 20 '14 at 02:18
  • yes i saw it..i am trying it..will inform you whether it is working or not – Parth Doshi Feb 20 '14 at 16:48
  • hi sorush-r. your code isnt working. the result from C++ and java do not match. Please can u add me on gmail. my gmail id is androidparth@gmail.com. Can u please send me a test message – Parth Doshi Feb 21 '14 at 18:38
  • I've tested this code and our company is using this for about 3 years. I'm pretty sure this is working well. Maybe there is something wrong in your Java code? – sorush-r Feb 22 '14 at 18:41
  • Please see this http://stackoverflow.com/questions/21965102/aes-256-encryption-qt-equivalent-for-java ..It clearly states my problem – Parth Doshi Feb 23 '14 at 06:44
  • OMG! @sorush-r your code seems to be complex unnecessarily and not readable. – S.M.Mousavi Jul 22 '21 at 05:45
  • @S.M.Mousavi Well, it's an old source code, but I am still open for all suggestions (: https://github.com/soroush/qtz-security/blob/dev/src/crypto.cpp#L50 – sorush-r Jul 22 '21 at 11:09