AES 256加密 - Qt等同于Java [英] AES 256 encryption - Qt equivalent for 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屋!