首页 > 代码库 > 这个发现是否会是RSA算法的BUG、或者可能存在的破解方式?
这个发现是否会是RSA算法的BUG、或者可能存在的破解方式?
笔者从事各种数据加解密算法相关的工作若干年,今天要说的是基于大数分解难题的RSA算法,可能有些啰嗦。
事情的起因是这样的,我最近针对一款芯片进行RSA CRT解密的性能优化。因为期望值是1024bits长度能做到20ms左右,但我的实现结果接近40ms。为了找到更加快速的实现方式,我在各大论坛查找不基于Jebelean和Montgomery的模乘实现。在查找过程中非常偶然的获得了一组密钥数据,现在按照一般生成密钥的顺序,先对该组数据简单说明一下,证明其正确性。
1. 密钥产生过程
选取两个512bits的大素数
P =
E3DB3B70833CFAC57472BE9234AECC4E0EECFD909015F199BDD109F05F89CE72B2CDAE24BD4D7923C1472DC719F9B987649C96675685D9F4EEDDA9EAE5C853EF
Q =
D534A891DB7899D60A917379105B9EE4589CB32046F850489539938C2EA8DF77A55BB21FA7B4FC30B2CAB67DF530918BB1267530F6A2E0C82765C5C96F27A21D
这两个数据,我使用Robin-Miller素数检测算法经过非常多次的验证,可以认定是素数(Robin-Miller素数检测是概率性检测,但可通过重复次数将概率变得极高)。
选取公钥E =
03
然后是费马小定理
计算φ(N) = (p - 1)(q - ) =
BDC447066192C96D3A4F6200885903E335A46BA0F989618F7158343F94BDC9BBEEB08CE1550C4D82655529D436B4FAAA790CB6CB463F43A62A9C78DE1B43B9600E99F4F9B78352EEC1D2E4E005AAF2C577872A5E153A90427CBB408BA658C28F8C075E205F6597814F76C3F9E4514C3E86F56409237B816813F624E0E247CA08
计算模数N = P * Q =
BDC447066192C96D3A4F6200885903E335A46BA0F989618F7158343F94BDC9BBEEB08CE1550C4D82655529D436B4FAAA790CB6CB463F43A62A9C78DE1B43B961C7A9D8FC1638E78A40D716EB4AB55DF7DF10DB0EEC48D224CFC5DE08348B7079E430BE64C4680CD5C388A83EF37B97519CB86FA170A43C252A3994953737C013
至此,就可以得到ND模式下的私钥D,D满足条件: E * D ≡ 1 % φ(N) ,则计算出私钥为D =
7E82DA04410C8648D18A4155B03B57ECCE6D9D15FBB0EBB4F63ACD7FB87E867D49CB089638B2DE56EE38C68D79CDFC71A60879DCD97F826EC712FB3EBCD7D0EAB466A35125023749D68C9895591CA1D8FA5A1C3EB8D1B581A87CD5B26EE5D70A5D5A3EC03F990FAB8A4F2D5142E0DD7F04A3980617A7AB9AB7F96DEB4185315B
下面随机选取一组数据作为密文,使用该私钥D对密文进行解密,密文cipher =
906BEA0B6BE3FBEFC0B4CA426B190424E955AD292AABF8D478A18261BCE7405932452D2CB9A7A8F17D5AAC920825CA5733FEEA5B2D1476BD4BBC16A83420082784DAEBD39FD2158E7264F49B4BC409DDDD1B0B5717F65D89264762D6F50A8C44C140429A4C84FD0FE620594A81674D6C47955BF7B090BFE352F59353BD3E470A
解密得到的明文为:plain = (cipher ^ D) % N =
75E796210F8064F78AB974858AD14FBB2ADEF2FF6316438BEA2E028E34EF602BF3D749536F73DE0E987F54468A1EB7B5F4FE77C472A282031B6286AAAD4D8444A4BED7F011C11CF1E2781AE9B7966B07317056ADAE4D13E83D8EA7486ED56FA8B1506D7FF2591FF94525193C2079052C18D584C7699CE64B1A16397D4696AA04
如果进一步使用该数据补全CRT模式下的5元子,过程如下:
DP = D % (P - 1) =
97E77CF5ACD351D8F84C7F0C231F32DEB49DFE60600EA111293606A03FB1344C7733C96DD388FB6D2B84C92F66A67BAF98686444E4593BF89F3E714743DAE29F
DQ = D % (Q - 1) =
8E231B0BE7A5BBE4070BA250B59269ED9068776AD9FAE030637BB7B2C9C5EA4FC39276BFC52352CB21DC79A94E206107CB6EF8CB4F1740856F992E864A1A6C13
QINV = (P ^ (-1)) % Q =
BD245407D1E2BF05D5AA4D7CFC55907B4FA03E8521BDC4C2BABC09AAF74FB4DA9A9238E115F1A3392AE97A546FDD1A4F6A23CE0A7B6106E2628503ED99D053E5
至此密钥数据计算以及随机选取的密文解密计算结束。
2. 发现问题
直到这里,整个计算过程完全没有问题。
我平时验证数据喜欢使用自己做的验证工具,但是这时我随手拿起公司的算法验证工具进行密钥补全操作,输入以上的P、Q、E长度指定为1024,然后计算出来的私钥为
D‘ =
1FA0B68110432192346290556C0ED5FB339B67457EEC3AED3D8EB35FEE1FA19F5272C2258E2CB795BB8E31A35E737F1C69821E77365FE09BB1C4BECFAF35F43AAD19A8D449408DD275A32625564728763E96870FAE346D606A1F356C9BB975C297568FB00FE643EAE293CB5450B8375FC128E60185E9EAE6ADFE5B7AD0614C57
与我通过标准计算流程得到的结果不一致。
当然了,经过计算可以知道这个私钥肯定不满足E * D‘ ≡ 1 % φ(N)d的条件,也就是说,这是一个非法私钥。
本着找茬的精神,我想找到公司的工具哪里出了问题,然后开始分析这组数据。
既然私钥D‘不合法,那我想看看它对密文解密能加出什么鬼来,于是我仍然使用上面的cipher作为密文,进行解密操作 plain‘ = (cipher ^ D‘) % N =
75E796210F8064F78AB974858AD14FBB2ADEF2FF6316438BEA2E028E34EF602BF3D749536F73DE0E987F54468A1EB7B5F4FE77C472A282031B6286AAAD4D8444A4BED7F011C11CF1E2781AE9B7966B07317056ADAE4D13E83D8EA7486ED56FA8B1506D7FF2591FF94525193C2079052C18D584C7699CE64B1A16397D4696AA04
到这里,问题就比较明显了。使用合法私钥D得到明文plain,使用非法密钥D‘得到明文plain‘
plain 与 plain‘ 完全相等。
我认为,RSA作为一个非对称算法,必然应该是公钥私钥一对一的,但是这组数据明显是一个公钥对应了两个私钥。尽管其中一组不合法,但是我尝试了几组数据后,发现解密所得明文均相等。
既然如此,我尝试着使用这个非法的D‘进行5元子的补齐:
DP‘ = D‘ % (P - 1) =
97E77CF5ACD351D8F84C7F0C231F32DEB49DFE60600EA111293606A03FB1344C7733C96DD388FB6D2B84C92F66A67BAF98686444E4593BF89F3E714743DAE29F
DQ‘ = D‘ % (Q - 1) =
8E231B0BE7A5BBE4070BA250B59269ED9068776AD9FAE030637BB7B2C9C5EA4FC39276BFC52352CB21DC79A94E206107CB6EF8CB4F1740856F992E864A1A6C13
接下来的QINV‘就不需要计算了,因为已经满足:
DP = DP‘
DQ = DQ‘
我仍不死心,认为两个私钥之间可能相差了若干个φ(N)导致可以计算出相同的结果,但是实际上两个私钥均小于φ(N),则两者的差绝无可能是φ(N)的倍数,且两个私钥均在N域以内。
3. 疑问
说到这里,便有了一个很大的问题,虽然不能从严格意义上说,这里发生了一个公钥对应两个私钥的情况,但是使用这个非法的私钥确确实实完成了合法私钥所能做的解密过程。
也就是说别人根本不需要知道我的私钥,而使用另外一组数据就可以完成签名,且这个签名使用我的公钥是完全可以通过延签的!!!!!!
这个问题我会持续的跟进,但是公司的工具我可能无法得到源码,所以还是有很大难度的。
发到这里,主要是想说清楚这个经过,以免有关RSA有一些比较特殊的情况,或者我的职业生涯中未曾涉猎的部分,当然也不排除计算过程中有什么失误的地方,欢迎大家使用数据进行验证,笔者整个验证均使用的OpenSSL库。
目前的计划是:抛开Robin-Miller素数检测算法,研究一下可以100%确定素数的算法,实在不行就穷举,先确认P 和 Q 确实是素数。其他可行的方案,也希望有相关知识的大牛指点一二,不吝赐教,小可不胜感激。
本人邮箱:heshuchao@hotmail.com
这个发现是否会是RSA算法的BUG、或者可能存在的破解方式?