首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java和c++加密结果不匹配

Java和c++加密结果不匹配
EN

Stack Overflow用户
提问于 2012-06-20 14:23:50
回答 2查看 1.6K关注 0票数 21

我有一个现有的c++代码,它将加密一个字符串。现在我做了同样的加密。一些加密的字符串是匹配的。有些字符在一个或两个字符中不匹配。

我不知道为什么会发生这种事。我在调试模式下运行了这两个代码,直到它们调用它们的库,它们都有相同的密钥,salt,iv字符串来进行加密。

我知道,即使一个字节填充更改将修改加密字符串急剧。但在这里,我只是看到一个或两个字符变化。这里是一个示例(星体之间的粗体字符是错误匹配的部分)

java:

U2FsdGVkX18xMjM0NTY3OGEL9nxFlHrWvodMqar82NT53krNkqat0rrgeV5FAJFs1vBsZIJPZ08DJVrQ*Pw*yV15HEoyECBeAZ6MTeN+ZYHRitKanY5jiRU2J0KP0Fzola

C++:

U2FsdGVkX18xMjM0NTY3OGEL9nxFlHrWvodMqar82NT53krNkqat0rrgeV5FAJFs1vBsZIJPZ08DJVrQ*jQ*yV15HEoyECBeAZ6MTeN+ZYHRitKanY5jiRU2J0KP0Fzola

我在使用AES加密。提供程序是SunJCE版本1.6。我试着把服务商换成了弹跳城堡。即使这样,结果也是一样的。

又增加了一个样本:

C++:

U2FsdGVkX18xMjM0NTY3O*I*/BMu11HkHgnkx+dLPDU1lbfRwb+aCRrwkk7e9dy++MK+/94dKLPXaZDDlWlA3gdUNyh/Fxv*oF*STgl3QgpS0XU=

java:

U2FsdGVkX18xMjM0NTY3O*D*/BMu11HkHgnkx+dLPDU1lbfRwb+aCRrwkk7e9dy++MK+/94dKLPXaZDDlWlA3gdUNyh/Fxv*j9*STgl3QgpS0XU=

更新:

根据评论,我觉得基础64加密是罪魁祸首。我在两个地方都使用拉丁语-1字符。其他我能查到的东西

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-20 21:11:10

叹息!!

问题几乎可以肯定的是,在加密数据并以字节字符串的形式接收加密数据之后,在通过Bas-64转换发送数据之前,您正在对数据进行某种类型的字符转换。

请注意,如果您对字符串"ABC__D__EFG“和"ABC_G_EFG”进行加密,则加密后的输出将完全不同,从第四个字符开始,一直到最后。换句话说,Bas-64输出应该类似于(使用虚构的值):

U2FsdGVkX18xMj

U2FsdGXt91mJpz

在上述示例中,每种情况下只有两个孤立的Bas-64字符(一个字节)被混淆,这很大程度上证明了加密后会发生损坏。

加密过程的输出是字节序列,而不是字符序列。所观察到的损坏与错误地将字节解释为字符和试图在其上执行代码页转换是一致的,然后再将它们输入Bas-64转换器。来自加密器的输出应该直接输入Bas-64转换器,而不需要任何转换。

你说你使用的是“拉丁语-1字符集在两个地方”,这是一个明确的标志,表明你正在做一些你不应该做的转换--不应该使用字符集。

票数 7
EN

Stack Overflow用户

发布于 2012-06-20 20:12:28

首先是一些代码:

代码语言:javascript
复制
import javax.xml.bind.DatatypeConverter;

..。

代码语言:javascript
复制
public static void main(String[] args) {
    String s1j = "U2FsdGVkX18xMjM0NTY3OGEL9nxFlHrWvodMqar82NT53krNkqat0rrgeV5FAJFs1vBsZIJPZ08DJVrQPwyV15HEoyECBeAZ6MTeN+ZYHRitKanY5jiRU2J0KP0Fzola";
    String s1c = "U2FsdGVkX18xMjM0NTY3OGEL9nxFlHrWvodMqar82NT53krNkqat0rrgeV5FAJFs1vBsZIJPZ08DJVrQjQyV15HEoyECBeAZ6MTeN+ZYHRitKanY5jiRU2J0KP0Fzola";
    byte[] bytesj = DatatypeConverter.parseBase64Binary(s1j);
    byte[] bytesc = DatatypeConverter.parseBase64Binary(s1c);
    int nmax = Math.max(bytesj.length, bytesc.length);
    int nmin = Math.min(bytesj.length, bytesc.length);
    for (int i = 0; i < nmax; ++i) {
        if (i >= nmin) {
            boolean isj = i < bytesj.length;
            byte b = isj? bytesj[i] : bytesc[i];
            System.out.printf("%s [%d] %x%n", (isj? "J" : "C++"), i, (int)b & 0xFF);
        } else {
            byte bj = bytesj[i];
            byte bc = bytesc[i];
            if (bj != bc) {
                System.out.printf("[%d] J %x != C++ %x%n", i, (int)bj & 0xFF, (int)bc & 0xFF);
            }
        }
    }
}

这件事

代码语言:javascript
复制
[60] J 3f != C++ 8d

现在,0x3f是问号的代码。

错误是,0x80-0xBF在拉丁文-1,正式的ISO-8859-1,控制字符。Windows拉丁语-1,正式的Windows-1252,使用这些代码为其他字符。

因此,您应该在Java中使用“Windows1252”或"Cp1252“(代码页)。

Blundly

在加密中,0x80范围内的原始字节。0xBF被替换为问号,因为它被转换为ISO-8859-1,而不是Windows1252到byte[]。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11121723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档