AES 256加密 - Qt等同于Java [英] AES 256 encryption - Qt equivalent for Java

查看:720
本文介绍了AES 256加密 - Qt等同于Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的AES 256加密方法实现,并在Java中工作正常如下:

 私有静态最终字节= {
0,2,4,8,16,32,64,127,
127,64,32,16,8,4,2,0
}

//这里的实际加密
私有静态字节[]加密(byte [] raw,byte [] clear)throws
异常{
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;
}

从上述方法返回的字节数组最终会转换为HEX字符串使用以下 toHex 方法。

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

因此,使用Java AES 256加密代码的最终结果是一个HEX字符串。 / p>

现在对于Qt部分,

  QByteArray IV 2,4,8,16,32,64,127,127,64,32,16,8,4,2,0);以及其组合,其中所述组合物包含: 


QString encrypt(QByteArray r,const QString& password)
{
const char * sample = r.data();
string plain = password.toStdString();
string ciphertext;
//生成密码,密钥和CBC
字节密钥[AES :: MAX_KEYLENGTH],iv [AES :: BLOCKSIZE];
StringSource(reinterpret_cast< const char *>(sample),true,
new HashFilter(*(new SHA256),new ArraySink(key,AES :: MAX_KEYLENGTH)
memset(iv,0x00,AES :: BLOCKSIZE);
CBC_Mode< AES> ::加密加密器(key,sizeof(key),iv);
StringSource(plain,true,new StreamTransformationFilter(Encryptor,
new HexEncoder(new StringSink(ciphertext))));
return QString :: fromStdString(ciphertext);
}

从main方法中调用上述函数

  QString encrypted = encrypt(result,test); 

其中result是 QByteArray 我传递加密做类似在java中。



在这两种情况下,字节数组的Java和Qt都是相同的。我已验证。



我的问题



Qt的加密逻辑是因为通过Java和Qt获得的 HEX 结果不匹配。



我在Qt部分做错了什么。我没有正确使用 IV QByteArray result

解决方案

我想你的Java实现错过了一个哈希步骤的键。我使用SHA256哈希的键。要测试c ++实现,请将代码更改为:

  QString加密(QByteArray r,const QString& password)
{
const char * sample = r.data();
string plain = password.toStdString();
string ciphertext;
//生成密码,密钥和CBC
字节密钥[AES :: MAX_KEYLENGTH],iv [AES :: BLOCKSIZE];
// StringSource(reinterpret_cast< const char *>(sample),true,
// new HashFilter(*(new SHA256),new ArraySink(key,AES :: MAX_KEYLENGTH)
for(int i = 0; i key [i] = reinterpret_cast< const char *>(decodedKey)[i]
}
memset(iv,0x00,AES :: BLOCKSIZE);
CBC_Mode< AES> ::加密加密器(key,sizeof(key),iv);
StringSource(plain,true,new StreamTransformationFilter(Encryptor,
new HexEncoder(new StringSink(ciphertext))));
return QString :: fromStdString(ciphertext);
}


I have my AES 256 encryption method implemented and working fine in Java as follows!

  private static final byte[] IV = {
    0, 2, 4, 8, 16, 32, 64, 127, 
    127, 64, 32, 16, 8, 4, 2, 0
};

  //actual encryption over here
  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;  
}  

The byte array that is returned from the above method is finally converted to a HEX string using the following toHex method.

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

So the end result using Java AES 256 encryption code is a HEX String.

Now for the Qt part,

  QByteArray IV("0, 2, 4, 8, 16, 32, 64, 127,127, 64, 32, 16, 8, 4, 2, 0");


 QString encrypt(QByteArray r, const QString &password)
 {
const char *sample = r.data();
string plain = password.toStdString();
string ciphertext;
// Generate Cipher, Key, and CBC
byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
StringSource( reinterpret_cast<const char *>(sample), 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);
} 

And from the main method i call the above function

        QString encrypted = encrypt(result, "test");

where "result" is a QByteArray that I pass to encrypt as done similarly in java.

The byte arrays in both cases Java and Qt are obtained the same. I have verified that.

My problem

The encryption logic for Qt especially is failing somewhere due to which the HEX result obtained via Java and Qt don't match.

Can anyone tell me what I am doing wrong in the Qt part. Am I not using the IV or the QByteArray result correctly?

解决方案

I guess your Java implementation misses a hash step on the key. I'm using a SHA256 hash of the key. To test c++ implementation, change code to this:

QString encrypt(QByteArray r, const QString &password)
 {
const char *sample = r.data();
string plain = password.toStdString();
string ciphertext;
// Generate Cipher, Key, and CBC
byte key[ AES::MAX_KEYLENGTH ], iv[ AES::BLOCKSIZE ];
//StringSource( reinterpret_cast<const char *>(sample), true,
//              new HashFilter(*(new SHA256), new ArraySink(key, AES::MAX_KEYLENGTH)) );
for(int i=0; i< AES::MAX_KEYLENGTH; ++i){
    key[i] = reinterpret_cast<const char *>(decodedKey)[i];
}
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);
} 

这篇关于AES 256加密 - Qt等同于Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆