在Java中使用openssl加密

在Java中使用openssl加密

Using openssl encryption with Java

我有一个传统的C ++模块,该模块使用openssl库(DES加密)提供加密/解密。 我正在尝试将该代码转换为Java,并且我不想依赖DLL,JNI等。
C ++代码如下所示:

1
2
3
4
5
6
7
8
9
des_string_to_key(reinterpret_cast<const char *>(key1), &initkey);
des_string_to_key(reinterpret_cast<const char *>(key2), &key);
key_sched(&key, ks);
// ...
des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()),
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey,
DES_ENCRYPT);

return base64(reinterpret_cast<const unsigned char *>(encrypted_buffer),    strlen(encrypted_buffer));

Java代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
Cipher ecipher;
try {
    ecipher = Cipher.getInstance("DES");
    SecretKeySpec keySpec = new SecretKeySpec(key,"DES");      
    ecipher.init(Cipher.ENCRYPT_MODE, keySpec);        
    byte[] utf8 = password.getBytes("UTF8");
    byte[] enc = ecipher.doFinal(utf8);
    return new sun.misc.BASE64Encoder().encode(enc);
}
catch {
    // ...
}

因此,我可以很轻松地用Java进行DES加密,但是如何使用完全不同的方法获得与上述代码相同的结果呢? 特别让我困扰的是C ++版本使用2个键,而Java版本仅使用1个键。
关于CBC模式下的DES的答案是相当令人满意的,但我还无法使它起作用。
以下是有关原始代码的更多详细信息:
unsigned char key1 [10] = {0};
unsigned char key2 [50] = {0};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int i;
for (i=0;i<8;i++)
    key1[i] = 31+int((i*sqrt((double)i*5)))%100;
key1[9]=0;

for (i=0;i<48;i++)
    key2[i] = 31+int((i*i*sqrt((double)i*2)))%100;
key2[49]=0;
...
// Initialize encrypted buffer
memset(encrypted_buffer, 0, sizeof(encrypted_buffer));

// Add begin Text and End Text to the encrypted message
std::string input;
const char beginText = 2;
const char endText = 3;
input.append(1,beginText);
input.append(bufferToEncrypt);
input.append(1,endText);    

// Add padding
tmp.assign(desPad(input));

des_ncbc_encrypt(reinterpret_cast<const unsigned char *>(tmp.c_str()),    
reinterpret_cast< unsigned char *>(encrypted_buffer), tmp.length(), ks, &initkey,
DES_ENCRYPT);
...

根据我的阅读,密钥应该是56位(或者64位,我不清楚),但是这里是48字节长。


另外,请记住,您实际上不应该在代码中使用sun.misc。*类。这可能会破坏其他VM,因为它们不是公共API。 Apache Commons编解码器(以及其他)具有不承担此问题的Base64实现。

我不太确定为什么单个DES会使用多个密钥。即使您使用的是Triple-DES,我相信您也可以使用单个密钥(具有更多字节的数据),而不是将单独的密钥与Java密码学API一起使用。


我不是OpenSSL专家,但是我猜C ++代码正在CBC模式下使用DES,因此需要一个IV(这就是initKey可能是的,这就是为什么您认为需要两个键)。如果我是对的,那么您还需要更改Java代码以在CBC模式下使用DES,那么Java代码也将需要加密密钥和IV。


算法应该匹配;如果得到不同的结果,则可能与处理键和文本的方式有关。还请记住,Java字符长2个字节,而C ++字符长1个字节,因此可能与此有关。


推荐阅读

    linux命令基础代码?

    linux命令基础代码?,基础,系统,管理,工作,代码,网络,单位,信息,数据,命令,lin

    linux打开代码命令行?

    linux打开代码命令行?,系统,首页,工具,终端,代码,密码,情况,命令,快捷键,窗

    linux克隆代码命令?

    linux克隆代码命令?,系统,代码,文件,命令,目录,源文件,文件夹,路径,目标,表

    linux加密压缩命令?

    linux加密压缩命令?,系统,网络,基础,管理,基础知识,积极,发展,下来,材料,电

    linux加密压缩命令?

    linux加密压缩命令?,系统,网络,基础,管理,基础知识,积极,发展,下来,材料,电

    linux命令行调试代码?

    linux命令行调试代码?,环境,代码,信息,平台,程序,编辑,版本,步骤,体系结构,

    linux编译源代码命令?

    linux编译源代码命令?,工具,代码,百度,最新,环境,项目,系统,电脑,密码,内核,l

    linux命令提交代码?

    linux命令提交代码?,工作,系统,地址,代码,命令,数据,信息,目录,标准,发行,求

    linux代码同步命令?

    linux代码同步命令?,时间,服务,系统,地址,代码,网络,通信,图片,风险,管理,lin

    linux命令错误代码?

    linux命令错误代码?,系统,密码,电脑,网络,手机,网址,软件,代码,设备,老板,Lin

    linux同步代码命令?

    linux同步代码命令?,时间,系统,通信,网络,标准,图片,服务,代码,线程,单位,Lin

    linux拉取代码命令?

    linux拉取代码命令?,代码,工作,地址,命令,数据,系统,单位,生产,软件,目录,lin

    linux命令详细解密?

    linux命令详细解密?,系统,地址,工作,命令,基础,信息,状态,数字,口令,目录,Lin

    linux代码对齐命令?

    linux代码对齐命令?,系统,地址,标准,信息,对比,名称,代码,命令,文件,工作,lin

    linux命令运行代码?

    linux命令运行代码?,代码,单位,系统,环境,连续,保险,工具,命令,文件,音乐,Lin

    搭建linux命令行代码?

    搭建linux命令行代码?,系统,软件,工作,名字,服务,代码,地址,环境,管理,密码,l

    linux查看命令代码?

    linux查看命令代码?,系统,信息,代码,名称,命令,设备,数字,第一,软件,管理,在L

    linux删除代码命令行?

    linux删除代码命令行?,系统,代码,命令,文件,不了,环境,档案,名称,目录,文件

    linux命令行代码实现?

    linux命令行代码实现?,标准,代码,管理,网络,地址,工作,命令,网上,环境,名称,

    linux模块化加载命令?

    linux模块化加载命令?,软件,系统,设备,代码,信息,环境,适当,资料,网上,电脑,