gpt4 book ai didi

java - 将Java加密算法移植到C++ OpenSSL

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:17 26 4
gpt4 key购买 nike

我在尝试通过 OpenSSL 在 C++ 中实现 Java 加密方法时遇到问题。

package des;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.bind.DatatypeConverter;

public final class Des
{
private static final byte[] IV = {(byte) 0xA6, (byte) 0x8A, 0x11, 0x63, (byte) 0x94, 0x4D, (byte) 0x8E, (byte) 0xA3};
private static final byte[] DES_KEY = {(byte) 0x81, 0x33, 0x66, (byte) 0xD8, 0x5F, (byte) 0xD3, 0x17, 0x21, 0x5C, 0x7F};

public static byte [] encrypt(String data)
{
byte result[] = null;
try
{
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(DES_KEY);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(IV);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
result = cipher.doFinal(data.getBytes(CHARSET));
}
catch(Exception e)
{
e.printStackTrace();
}
return result;
}
}

测试:

import des.Des;

class DesCrypt
{
public static void main(String args[])
{
byte array[] = Des.encrypt("my secret string");
for(byte b : array)
{
System.out.printf("%02X ", b);
}
}
}

加密后的结果为:

0B AE 3C 47 B5 CE 57 03 01 25 F7 1B 1B 1D F4 C1 50 66 90 1F 7E B3 89 FD 

我没有密码学经验,所以我决定使用 DES_cbc_encrypt() 在 C++ 中实现“DES/CBC/PKCS5Padding”加密。

#include <vcl.h>
#pragma hdrstop

#include <tchar.h>
#include <string>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <stdio.h>
#include <openssl/des.h>

#pragma argsused

class Des
{
public:
typedef std::vector<unsigned char> Bytes;
static Bytes encrypt(const std::string& message)
{
const unsigned char IV[] = {0xA6, 0x8A, 0x11, 0x63, 0x94, 0x4D, 0x8E, 0xA3};
const unsigned char key[] = {0x81, 0x33, 0x66, 0xD8, 0x5F, 0xD3, 0x17, 0x21, 0x5C, 0x7F};
const Bytes in(message.begin(), message.end());
DES_cblock desKey = {0};
DES_cblock iv = {0};
std::copy(key, key + 8, desKey);
std::copy(IV, IV + 8, iv);
DES_key_schedule keysched;
Bytes result(in.size());
DES_set_odd_parity(&desKey);
if(DES_set_key_checked((C_Block *)desKey, &keysched))
{
throw std::runtime_error("ERROR: Unable to set key schedule");
}
DES_cbc_encrypt(&in[0], &result[0], in.size(), &keysched, &iv, DES_ENCRYPT);
return result;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
const Des::Bytes encr = Des::encrypt("my secret string");
size_t size = encr.size();
for(Des::Bytes::const_iterator byte = encr.begin(); byte != encr.end(); ++byte)
{
printf("%02X ", *byte);
}
return 0;
}

结果是:

0B AE 3C 47 B5 CE 57 03 01 25 F7 1B 1B 1D F4 C1

Java 输出最后有 8 个额外的字节。请帮助选择合适的 OpenSSL 函数以在 C++ 中实现与 Java DES/CBC/PKCS5Padding 加密算法提供的相同结果。提前致谢。

最佳答案

正如@Artjom B. 建议的那样,我根据规范实现了 PKCS#5 填充

6.1.1   Encryption Operation

...

4. Concatenate M and a padding string PS to form an encoded
message EM:

EM = M || PS ,

where the padding string PS consists of 8-(||M|| mod 8) octets
each with value 8-(||M|| mod 8). The padding string PS will
satisfy one of the following statements:

PS = 01, if ||M|| mod 8 = 7 ;
PS = 02 02, if ||M|| mod 8 = 6 ;
...
PS = 08 08 08 08 08 08 08 08, if ||M|| mod 8 = 0.

代码:

class Des
{
public:
typedef std::vector<unsigned char> Bytes;
static Bytes encrypt(const std::string& message)
{
const unsigned char IV[] = {0xA6, 0x8A, 0x11, 0x63, 0x94, 0x4D, 0x8E, 0xA3};
const unsigned char key[] = {0x81, 0x33, 0x66, 0xD8, 0x5F, 0xD3, 0x17, 0x21, 0x5C, 0x7F};
Bytes in(message.begin(), message.end());
DES_cblock desKey = {0};
DES_cblock iv = {0};
std::copy(key, key + 8, desKey);
std::copy(IV, IV + 8, iv);
DES_key_schedule keysched;
const size_t paddingLength = (8 - in.size() % 8);
const Bytes padding(paddingLength, 8 - in.size() % 8);
std::copy(padding.begin(), padding.end(), back_inserter(in));
Bytes result(in.size());
DES_set_odd_parity(&desKey);
if(DES_set_key_checked((C_Block *)desKey, &keysched))
{
throw std::runtime_error("ERROR: Unable to set key schedule");
}
DES_cbc_encrypt(&in[0], &result[0], in.size(), &keysched, &iv, DES_ENCRYPT);
return result;
}
};

现在输出等同于 Java 实现输出。

关于java - 将Java加密算法移植到C++ OpenSSL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30478025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com