Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解密中去除填充的算法有问题 #14

Open
baoyongzhang opened this issue Jul 19, 2018 · 22 comments
Open

解密中去除填充的算法有问题 #14

baoyongzhang opened this issue Jul 19, 2018 · 22 comments

Comments

@baoyongzhang
Copy link
Contributor

image
这个算法有问题,这里应该是把后面填充的内容去掉吧,不足16填充几个几,这里忽略 0x0a,0A对应ascii码里的 \n ,这样的话,如果正好差 10 位不足 16,那就会填充 10 个 10 ,10 就是 0x0A,解密之后的原文后面会出现 10个 \n。

@BruceWind
Copy link
Owner

你的解密的秘文发我测试一下,这里 != 0x0a 是故意加的,有人解密的的原文里有换行,导致换行后的内容丢了。

@baoyongzhang
Copy link
Contributor Author

我用 “111111” 6个原文测试,密文是 “yiCLSX8FMSs16AnRdrsscA==”。
这是密文,只要是原文长度除以16余10的情况都会出现,比如原文是6个1,或者22个1,

@baoyongzhang
Copy link
Contributor Author

忘了,我这个密钥改了,你应该解密不了,你直接用 6个1加密在解密就行

@BruceWind
Copy link
Owner

BruceWind commented Jul 19, 2018

private final String str = "111111";

    //下面的密文对应的原文:123abcABC&*(@#@#@)+_/中文测试
    String code = AESEncrypt.encode(this, str);

    Log.d("code", code + "");
    Log.d("code", AESEncrypt.decode(this,code) + "");

log :

07-19 11:36:52.364 5799-5799/com.androidyuan.aesjniencrypt D/code: rfTzn9WjsDFbK262m0k4xg==
07-19 11:36:52.365 5799-5799/com.androidyuan.aesjniencrypt D/code: 111111


我测试 :看上去没有问题啊 ?

@BruceWind
Copy link
Owner

“这里应该是把后面填充的内容去掉吧,不足16填充几个几”
第一句说对了,第二句不对,没有填充,你看返回的Jstring真实的值,后面的字符被忽略了。

使用这个函数的位置:

    //去除结尾垃圾字符串 begin
    int index = findPaddingIndex(out);
    if(index==NULL)
    {
        return (char*)out;
    }
    if(index < strlen(out)){//  if (index>strlen)  will crash.
        memset(out+index, '\0', strlen(out)-index);
    }
    //去除结尾垃圾字符串 end

@baoyongzhang
Copy link
Contributor Author

log里打印看不到\n。
image
断点可以看到,或者你打印的时候 + "end" 后面加字符串,打印出来可以看到好几个换行。
image

@BruceWind
Copy link
Owner

好的。我再看下 。。。

@BruceWind
Copy link
Owner

测试了,确实如此,这个问题,需要后面我来改下,我之前故意跳过了"\n"字符串,你急着使用到商业项目中的话,可以先把那个if里的东西删掉,但是,你的原文中一定不能有'\n' ,否则'\n'之后的东西就会丢失。

@BruceWind
Copy link
Owner

BruceWind commented Jul 19, 2018

if (HEX[k]==c && HEX[k]!= 0x0a)

to

  if (HEX[k]==c)

@baoyongzhang
Copy link
Contributor Author

好的,我也尝试解决一下

@BruceWind
Copy link
Owner

你弄好了,可以推一个pull request给我。

@BruceWind
Copy link
Owner

我大概知道怎么改了:

这个方法 findPaddingIndex(uint8_t * str)

for循环应该从后往前查,查到第一个有效字符的位置,停止。

    for (i = strlen(str); i >=0 ; i--) 

@baoyongzhang
Copy link
Contributor Author

没办法确定什么是有效字符呀,就拿 \n 来说,填充的10个10的时候就是填充了 10个\n,解密之后应该去掉这10个10,但是你没办法知道这个\n是加密的时候填充的还是原文就存在的。
我的想法是,既然填充方法是不足16就填充几个几,可以直接取最后一个值,如果是10,就减去10,是多少减去多少,这样就加密填充的时候方法对应上的。

int findPaddingIndex(uint8_t * str)
{
    int len = strlen(str);
    return len - str[len - 1];
}

@BruceWind
Copy link
Owner

BruceWind commented Jul 19, 2018

是的。

你可以试试 ,\n在开头 在中间 在结尾 ,各种情况,解密出来 有没有丢\n。

@baoyongzhang
Copy link
Contributor Author

现在这种遍历的写法,必须有一个前提,那就是原文中不能存在 1-16 的字符,如果有就会被忽略掉,一般情况下确实不会出现,\n是10,除了\n常见之外,其他的很难碰到了。

@BruceWind
Copy link
Owner

Sorry every one, AES is no longer supported.
I have pushed code that use chacah20 instead of AES. #40

@BruceWind
Copy link
Owner

关于**\n或者空格**字符串丢失问题。

我在libsodium上会遇到同样的问题,我的solution是这样子:13d589890ecae106985bf91897243eb8f55e8bc5.

@pangli
Copy link

pangli commented Feb 7, 2023

这个\n问题最后怎么解决的?

@BruceWind
Copy link
Owner

BruceWind commented Feb 7, 2023

我的solution是这样子:13d589890ecae106985bf91897243eb8f55e8bc5.

跨语言传递参数时,用base64传。Base64的字符串就不会遇到特殊字符了。

@pangli
Copy link

pangli commented Feb 8, 2023

我的solution是这样子:13d589890ecae106985bf91897243eb8f55e8bc5.

跨语言传递参数时,用base64传。Base64的字符串就不会遇到特殊字符了。

这确实也是一个方法,在原生代码上先转成base64

@BruceWind
Copy link
Owner

感谢您使用此项目,但这个项目已经很久没再跑测试了。如遇编译问题,请及时提issue,我会尽量及时回复。

@BruceWind
Copy link
Owner

@pangli 忘了说,新分支已经关闭混淆(扰乱)的功能了。之前更换加密算法后,忘了把这部分代码跑通。
开启扰乱的一些配置见:#5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants