首页
社区
课程
招聘
[求助]字符串加密,没有更好的方法了吗?
2010-6-15 17:12 14679

[求助]字符串加密,没有更好的方法了吗?

2010-6-15 17:12
14679
最近做一个项目,需要对字符串加密,因此,上网搜了下大致的加密方式,但这些方式都无法满足我的需求。
    我的需求是,用户可以选择任意字符串进行加密,如果需要加密的话,要求输入密码,验证密码成功的话,根据用户的密码对该字符串进行解密。最重要的是,要求加密后的内容与用户输入的密码有关联,也就是说,当我程序里的语句
if(password == userinput) 这句即使被用disassembly方式破解,解出来的也只能是乱码!
    而网上介绍的方式,全部是直接对字符串采用md5,rsa或其他加密方式直接对字符串进行加密,而这些加密方式基本上跟用户的密码无关。这样的加密方式即使再复杂,但只要对if(password == userinput)语句的汇编指令被篡改,根本没有安全性可言。
    请教各位大侠,有没有符合我要求的用字符串作为key,对字符串加密又能解密的方式?当然,如果可以的话,最好是能在不保存密码的情况下,能够仅仅凭借用户输入的密码与加密后的字符串就能够验证密码的正确性是最好的啦。
                                 先谢过愿意抽时间前来讨论的坛友啦。

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞0
打赏
分享
最新回复 (19)
雪    币: 24
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ipfans 2010-6-15 18:50
2
0
基本上有逻辑判断必然有分支的......
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-15 20:47
3
0
刚才在回家的路上想到了一个权宜之计。
加密步骤:
1、在内容字符串尚未加密之前,先通过算法(rsa,md5...)生成数字签名。
2、通过算法(rsa,md5...)生成密码字符串的数字签名。
3、将内容字符串与通过密码字符串生成的数字签名逐字的循环异或。
解密步骤:
1、将用户输入的密码字符串通过算法(rsa,md5...)生成密码字符串的数字签名
2、将内容字符串与通过密码字符串生成的数字签名逐字的循环异或还原
3、将解密后的内容字符串通过算法(rsa,md5...)生成数字签名
4、将当前的内容字符串的数字签名与保存在某个地方的原来的内容字符串的数
   字签名进行比较,如果不一样就说明密码是错的。
通过以上的加解密步骤达到了两个目的:
1、不用保存用户密码字符串或密码字符串的数字签名到程序的任何地方。
2、即使遭遇破解他得到的仅仅是乱码。

    这样的话就达到了我的目的。不过为什么说是权宜之计呢?
这个方式有两个缺点:
1、判断用户输入的密码是否是错误的之前,必须进行一次解密操作。
2、必须保存内容字符串的数字签名,算法不纯洁。

据我所知,winzip的加密算法就是不用先解压就可以知道密码的正确与否,
并且,我的猜测是它也根本不会去简单的保存密码的任何信息在压缩文件中,
否则,早就被破解了。就是不知道他是咋弄的。
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-15 21:24
4
0
找到最终的方案,用aes算法可以直接用字符串密钥对字符串加密!
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
denial 2010-6-15 21:28
5
0
画个程序流程图,这样大家比较容易懂。
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-15 22:36
6
0
晚上找了很多aes算法的资料,好像没有人针对unicode 字符串实现aes算法。疑惑中!,是我没找到相关资料,还是aes算法不支持unicode? (注:在内部先将unicode转换成ansi字符串再使用aes算法的不算)
雪    币:
能力值: (RANK: )
在线值:
发帖
回帖
粉丝
游客 2010-6-17 20:38
7
0
为什么一定要把它当字符串来处理呢? 要知道所谓的AES, DES等等算法只是针对一个输入数据流, 它并不关心这个输入数据流中到底是ANSI码还是Unicode.
你觉得加密 "ABCDE" 和加密 { 0x41, 0x42, 0x43, 0x44, 0x45 } 有区别吗?
PS: 使用对称算法意味着加/解密所用的密钥会发布到用户手上.
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-17 21:53
8
0
是的,我错了,加密程序时不管你传过来的是什么的,全部当成二进制串来处理。
不过楼上说的有一点不对,aes是可以不需要把密钥发给用户的,密码错了就只管让他都是乱码呗。
只不过很少人这么做,现在我的方案是,用aes加密字符串,将用户的密码用md5加密,解密的时候
先验证md5,正确了再用aes解密字符串。比较坏的情况是验证md5这一步遭遇disembly篡改,但是
他得到的只能是乱码。最坏的情况是,他能通过md5还原密码,这种情况我就不管了。毕竟概率很小。
另外有一个问题是,我的aes是用cfb模式并且是256位加密的,应该破解不了吧?
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
meiqiyuan 2010-6-17 22:35
9
0
我有个问题

确实,aes目前无法被破解

目前方法,只有知道了aes的密钥,

好了,又回到了原来的问题

如何保护aes的密钥

这个问题就是LZ的问题(如何保护字符串)
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-17 22:58
10
0
我现在用md5保存用户的密码,用户密码的明文不做任何的保存。需要解密的时候需要用户实时输入密码,与md5进行验证。
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
meiqiyuan 2010-6-17 23:13
11
0
我问你

明文:我是明文
密文:我是密文
密钥:我是密钥
MD5:我是密钥的MD5

密文->密钥->明文->密钥->密文

密文->密钥的MD5->明文->密钥的MD5->密文

我请问你 MD5有什么用
雪    币: 67
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
没有姓名 2010-6-18 03:08
12
0
我想楼主可能把问题想复杂了。将用户的输入生成一个密钥(最简单的方法就是保持不变,然后进行必要的填充或者压缩),用这个密钥来加密和解密数据。
请将字符串全部当作一般的二进制数据来理解;用户的输入的是字符串,也当作是一般的二进制数据来处理。
随便用一个对称加密都可以满足楼主的需求,根本不需要进行if(aa==bb)之类的判断。至于解密是否正确,一般是通过数据校验来实现的。

之所以很多引用需要对用户输入的密码进行MD5处理,一方面是为了防止中间人攻击,另一方面是因为主流的对称加密的密钥的长度都是某个固定的值,而用户设置的密码长度是不固定的,而且很多时候用户密码长度超过加密密钥的长度,所以需要用MD5压缩为固定的长度。
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
jackozoo 14 2010-6-18 13:17
13
0
楼上说的已经很清楚了,也是比较正规的做法。
至于楼主的先MD5验证然后密码原文解密也是可以达到目的的,只不过一般不这么做。
按你的要求,可以在对字符串加密时,先计算好明文的一个校验值附在密文后面。然后解密函数
bool DecryptString(...)直接将用户输入作为密匙(位数不够或超过自行调整)去解密,解密后再算一次校验值,与之前密文尾部的校验值进行比较,如果不同则return false,即密码错误,否则则成功。

楼主没把问题说清楚,导致大家可能没理解你的意思,你的第二行第二个逗号后的文字没说清楚,红色的应该是"解密"吧:
如果需要加密的话,要求输入密码,验证密码成功的话,根据用户的密码对该字符串进行解密。
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-18 15:00
14
0
哦,是哦,我可能打错字了,真对不起。
回楼上的,您说的校验值是指crc32算法吧? 那和md5还不是一回事?,而且您这么做的话,如果用户密码错误,那这个错误的密码去解密时多余的操作。而且把校验值放在密文的尾部,那解密的时候还得
先把校验值剔除,也太麻烦了吧。我直接加字段了,叫passwordmd5,不是很方便?而且密码错误,也不用再做多余的解密操作。
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
jackozoo 14 2010-6-18 17:52
15
0
MD5,CRC32都是一个hash而已,从某种角度来说确实区别不大。但是你先理清楚,你比较的MD5的值是用户密码的MD5,我上面说的校验是对明文内容的校验。有区别吗? 有:
既然是在做安全那就要全方位考虑问题。从用户的角度考虑,因为你仅仅只是对字符串加密,普通用户根本不会去设置一个过于复杂的密码。这时候MD5的安全性就大打折扣了,我想只是诸如cmd5,xmd5之类的网站就可以轻松得到密码原文了,暂不说彩虹表之类的手段。

另外,解密操作所占用的CPU时间几乎可以忽略,这些指令都是些纯粹的寄存器内存操作。一个好的程序真正需要减少的是I/O操作。为了保证安全性,每次都去解密一下又何妨了。

我也只是从安全的角度给你个建议而已,因为我见过的都是这种手法,如果你认为MD5足够安全那也无妨。
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-18 21:23
16
0
嗯,很有道理,采用您的建议不做密码的md5了,改为做整个字符串的md5。
不过有一点不明白的是,好像大部分破解都是针对md5来的,crc32好像类似的破解网站比较少?
难道还要折腾一下crc32? 请教版主,有必将好不容易弄好的md5算法改成crc32吗?
雪    币: 1450
活跃值: (35)
能力值: (RANK:680 )
在线值:
发帖
回帖
粉丝
jackozoo 14 2010-6-18 22:16
17
0
没必要了。
针对MD5的破解多般是对密码的破解。密码对于用户来说才是比较敏感的也比较重要的东西。
你用MD5对字符串计算hash是可以的,就算别人破解了这个字符串(这种概念很低,除非这个字符串确实太过于简单或者长的太像密码),他也只是破解了这一个字符串而已,下一个字符串他就不一定破解的了。所以MD5 CRC32都行,看你个人喜好了,都没问题的。

不过,我认为CRC32比MD5要简单一些,算法如下:
//生成CRC32的码表
void CreateCrc32Table(
					  OUT LPDWORD pCrc32Table           //大小为256双字的数组
                      )
{
    for (int i=0; i<0x100; i++)
    {
        DWORD crc = i;
        for (int j=0; j<8; j++)
        {
            if (crc & 1)
            {
                crc >>= 1;
                crc ^= 0xEDB88320;
            }
            else
            {
                crc >>= 1;
            }
        }
        pCrc32Table[i] = crc;
    }
}

//计算给定数据的CRC值
DWORD CalculateCrc32(
                     IN LPBYTE pData,             //源数据块首地址
                     IN DWORD dwSize,              //源数据块大小
                     IN LPDWORD pCrc32Table       //由CreateCrc32Table生成的数据表
                     )
{
    DWORD crc = -1;
    
    while (dwSize--)
    {
        crc = (crc >> 8) ^ pCrc32Table[(crc ^ *pData++) & 0xff];
    }
    return ~crc;
}
void main()
{
    DWORD crc32Table[256];
    CreateCrc32Table(crc32Table);
    //然后直接调用计算CRC的函数即可
   DWORD dwCRC32 = CalculateCrc32(... ... ...);
    ...

}
雪    币: 215
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ooseven 2010-6-18 22:50
18
0
谢谢版主贡献的源码。记录下了!
再请教一个问题,都说sha1比md5的安全性高。不过貌似md5现在除了穷举与查字典外并无法实现破解。王小云
的那个破解算法也无法进行特定碰撞,只不过证明了md5算法在两份不同内容的数据会有相同的哈希值而已,实际上
sha1也存在同样的问题。
这样一来sha1好像也没有什么优势,穷举与查表同样适用于破解sha1,而且它的速度又比md5慢那么多,不知道它存在的意义在哪里?
雪    币: 67
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
没有姓名 2010-6-19 09:29
19
0
http://it.solidot.org/article.pl?sid=09/01/01/050232
在第25届Chaos Communication Congress(CCC)会议上,研究人员透露他们可以用MD5碰撞创造假的数字证书认证(certificate authority),利用200台PS3,他们能在短时间破解SSL加密。 当你通过HTTPS安全连接访问网站时,一个数字证书将从服务器发送到你的电脑上。证书包含了一个验证网站身份的数字签名。签名来自数字证书认证中心 (CA),它的角色相当于中间人。你信任CA,也就信任它的签名。任何人都能创造一个数字证书,因此浏览器如Firefox 3有一个可信任的CA列表,如果CA值得信任,浏览器就会认为它的证书也是可信的。CA使用的公开密钥也在逐步进化,从MD5算法到现在比较流行的 SHA-1和SHA-2。安全研究人员和数学家几年前就证明,MD5算法、SHA-0和SHA-1算法都是弱安全的,可通过碰撞方法破解。 在CCC大会上,安全研究人员利用200台PS3攻击MD5算法,创造了一个假的来自可信CA的数字证书。研究人员表示用不着恐慌(PDF),受影响的 CA可以换用SHA-1、SHA-2,甚至是SHA-3。


http://zh.wikipedia.org/w/index.php?title=MD5&variant=zh-cn
MD5较老,散列长度通常为128位,随着计算机运算能力提高,找到“碰撞”是可能的。因此,在安全要求高的场合不使用MD5。

2004年,王小云证明MD5数字签名算法可以产生碰撞[1]。2007年,Marc Stevens,Arjen K. Lenstra和Benne de Weger进一步指出通过伪造软件签名,可重复性攻击MD5算法[2]。研究者使用前缀碰撞法(chosen-prefix collision),使程序前端包含恶意程序,利用后面的空间添上垃圾代码凑出同样的MD5 Hash值。

2008年,荷兰埃因霍芬技术大学科学家成功把2个可执行文件进行了MD5碰撞,使得这两个运行结果不同的程序被计算出同一个MD5[3]。 2008年12月一组科研人员通过MD5碰撞成功生成了伪造的SSL证书,这使得在https协议中服务器可以伪造一些根CA的签名。[4]


现在很多网站采用MD5+SHA-1双检验的方式发布代码。
雪    币: 67
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
没有姓名 2010-6-19 10:00
20
0
http://it.solidot.org/article.pl?sid=09/01/01/050232
在第25届Chaos Communication Congress(CCC)会议上,研究人员透露他们可以用MD5碰撞创造假的数字证书认证(certificate authority),利用200台PS3,他们能在短时间破解SSL加密。 当你通过HTTPS安全连接访问网站时,一个数字证书将从服务器发送到你的电脑上。证书包含了一个验证网站身份的数字签名。签名来自数字证书认证中心 (CA),它的角色相当于中间人。你信任CA,也就信任它的签名。任何人都能创造一个数字证书,因此浏览器如Firefox 3有一个可信任的CA列表,如果CA值得信任,浏览器就会认为它的证书也是可信的。CA使用的公开密钥也在逐步进化,从MD5算法到现在比较流行的 SHA-1和SHA-2。安全研究人员和数学家几年前就证明,MD5算法、SHA-0和SHA-1算法都是弱安全的,可通过碰撞方法破解。 在CCC大会上,安全研究人员利用200台PS3攻击MD5算法,创造了一个假的来自可信CA的数字证书。研究人员表示用不着恐慌(PDF),受影响的 CA可以换用SHA-1、SHA-2,甚至是SHA-3。
http://zh.wikipedia.org/w/index.php?title=MD5&variant=zh-cn
MD5较老,散列长度通常为128位,随着计算机运算能力提高,找到“碰撞”是可能的。因此,在安全要求高的场合不使用MD5。

2004年,王小云证明MD5数字签名算法可以产生碰撞[1]。2007年,Marc Stevens,Arjen K. Lenstra和Benne de Weger进一步指出通过伪造软件签名,可重复性攻击MD5算法[2]。研究者使用前缀碰撞法(chosen-prefix collision),使程序前端包含恶意程序,利用后面的空间添上垃圾代码凑出同样的MD5 Hash值。

2008年,荷兰埃因霍芬技术大学科学家成功把2个可执行文件进行了MD5碰撞,使得这两个运行结果不同的程序被计算出同一个MD5[3]。 2008年12月一组科研人员通过MD5碰撞成功生成了伪造的SSL证书,这使得在https协议中服务器可以伪造一些根CA的签名。[4]
现在很多网站采用MD5+SHA-1双检验的方式发布代码。
最后送上一篇文章,介绍的是如何进行前缀碰撞。

再增加一个老外根据Wang的文章写的代码,用于产生MD5碰撞,据说普通PC机平均运行20分钟就可以了。
md5toolkit.rar
上传的附件:
游客
登录 | 注册 方可回帖
返回