多谢各位关注,问题原因已经确定,现决定结贴!
总结一下:
每对RSA密钥均存在至少一组非法私钥,且非法私钥可以正常进行密钥补全和解密;
对用户来说,并没有影响;
安全性上,暴力破解时间复杂度会有一些减小,但是对个人电脑速度来说,也基本忽略了。
可能我最开始野心太大,总想着找找RSA的茬,却没有先想着从原理上找到出现这种情况的原因,也感谢@Mike_Dog的及时指点。尽管如此,我还是会对权威的东西保持怀疑,另外AKS素数检测算法也会继续跟进。
再次感谢!
==============================2017.01.23夜更新==============================
再次感谢@Mike_Dog的评论,现在具体原因已经分析完毕!在这里详细描述一下出现这种情况的原因。
再次罗列一下原文提到的密钥数据。
5元子如下:
P =
E3DB3B70833CFAC57472BE9234AECC4E0EECFD909015F199BDD109F05F89CE72B2CDAE24BD4D7923C1472DC719F9B987649C96675685D9F4EEDDA9EAE5C853EF
Q =
D534A891DB7899D60A917379105B9EE4589CB32046F850489539938C2EA8DF77A55BB21FA7B4FC30B2CAB67DF530918BB1267530F6A2E0C82765C5C96F27A21D
φ(N) = (p - 1)(q - ) =
BDC447066192C96D3A4F6200885903E335A46BA0F989618F7158343F94BDC9BBEEB08CE1550C4D82655529D436B4FAAA790CB6CB463F43A62A9C78DE1B43B9600E99F4F9B78352EEC1D2E4E005AAF2C577872A5E153A90427CBB408BA658C28F8C075E205F6597814F76C3F9E4514C3E86F56409237B816813F624E0E247CA08
D =
7E82DA04410C8648D18A4155B03B57ECCE6D9D15FBB0EBB4F63ACD7FB87E867D49CB089638B2DE56EE38C68D79CDFC71A60879DCD97F826EC712FB3EBCD7D0EAB466A35125023749D68C9895591CA1D8FA5A1C3EB8D1B581A87CD5B26EE5D70A5D5A3EC03F990FAB8A4F2D5142E0DD7F04A3980617A7AB9AB7F96DEB4185315B
DP = D % (P - 1) =
97E77CF5ACD351D8F84C7F0C231F32DEB49DFE60600EA111293606A03FB1344C7733C96DD388FB6D2B84C92F66A67BAF98686444E4593BF89F3E714743DAE29F
DQ = D % (Q - 1) =
8E231B0BE7A5BBE4070BA250B59269ED9068776AD9FAE030637BB7B2C9C5EA4FC39276BFC52352CB21DC79A94E206107CB6EF8CB4F1740856F992E864A1A6C13
QINV = (P ^ (-1)) % Q =
BD245407D1E2BF05D5AA4D7CFC55907B4FA03E8521BDC4C2BABC09AAF74FB4DA9A9238E115F1A3392AE97A546FDD1A4F6A23CE0A7B6106E2628503ED99D053E5
N = P * Q =
BDC447066192C96D3A4F6200885903E335A46BA0F989618F7158343F94BDC9BBEEB08CE1550C4D82655529D436B4FAAA790CB6CB463F43A62A9C78DE1B43B961C7A9D8FC1638E78A40D716EB4AB55DF7DF10DB0EEC48D224CFC5DE08348B7079E430BE64C4680CD5C388A83EF37B97519CB86FA170A43C252A3994953737C013
以上按照正确的RSA密钥产生方式依次计算。
产生问题的计算方式如下:
在计算φ(N)的时候,如果在计算之前将P-1和Q-1的公因子约掉(P-1和Q-1均为偶数,可以约掉一个2),则
(P- 1) / 2 =
71ED9DB8419E7D62BA395F491A57662707767EC8480AF8CCDEE884F82FC4E7395966D7125EA6BC91E0A396E38CFCDCC3B24E4B33AB42ECFA776ED4F572E429F7
(Q - 1) / 2 =
6A9A5448EDBC4CEB0548B9BC882DCF722C4E5990237C28244A9CC9C617546FBBD2ADD90FD3DA7E1859655B3EFA9848C5D8933A987B51706413B2E2E4B793D10E
此时,φ'(n) = ((P- 1) / 2)((Q- 1) / 2) =
2F7111C19864B25B4E93D880221640F8CD691AE83E625863DC560D0FE52F726EFBAC23385543136099554A750DAD3EAA9E432DB2D18FD0E98AA71E3786D0EE5803A67D3E6DE0D4BBB074B938016ABCB15DE1CA97854EA4109F2ED022E99630A3E301D78817D965E053DDB0FE7914530FA1BD590248DEE05A04FD89383891F282
则按照这个φ'(n)计算得到的私钥,满足E * D' ≡ 1 % φ'(N)的D' =
1FA0B68110432192346290556C0ED5FB339B67457EEC3AED3D8EB35FEE1FA19F5272C2258E2CB795BB8E31A35E737F1C69821E77365FE09BB1C4BECFAF35F43AAD19A8D449408DD275A32625564728763E96870FAE346D606A1F356C9BB975C297568FB00FE643EAE293CB5450B8375FC128E60185E9EAE6ADFE5B7AD0614C57
与前文提到的非法私钥完全一致。
按照这个计算流程,可以知道D' = D % φ'(n),也就解释了为什么这个D'对于5元子补全以及解密操作完全没有影响。
其实按照这个思路,还可以有两种方式得到这个非法私钥。
如果计算φ''(n) = (P- 1)((Q- 1) / 2) =
5EE2238330C964B69D27B100442C81F19AD235D07CC4B0C7B8AC1A1FCA5EE4DDF7584670AA8626C132AA94EA1B5A7D553C865B65A31FA1D3154E3C6F0DA1DCB0074CFA7CDBC1A97760E9727002D57962BBC3952F0A9D48213E5DA045D32C6147C603AF102FB2CBC0A7BB61FCF228A61F437AB20491BDC0B409FB12707123E504
或者计算φ'''(n) = ((P- 1) / 2)(Q- 1) =
5EE2238330C964B69D27B100442C81F19AD235D07CC4B0C7B8AC1A1FCA5EE4DDF7584670AA8626C132AA94EA1B5A7D553C865B65A31FA1D3154E3C6F0DA1DCB0074CFA7CDBC1A97760E9727002D57962BBC3952F0A9D48213E5DA045D32C6147C603AF102FB2CBC0A7BB61FCF228A61F437AB20491BDC0B409FB12707123E504
这两个值是相等的,则满足E * D'' ≡ 1 % φ''(N)的D'' =
1FA0B68110432192346290556C0ED5FB339B67457EEC3AED3D8EB35FEE1FA19F5272C2258E2CB795BB8E31A35E737F1C69821E77365FE09BB1C4BECFAF35F43AAD19A8D449408DD275A32625564728763E96870FAE346D606A1F356C9BB975C297568FB00FE643EAE293CB5450B8375FC128E60185E9EAE6ADFE5B7AD0614C57
也就是原文中的非法私钥。
然后要说的就是产生这个问题的原因,按照上面的计算方式,可以为所有的RSA密钥计算得到一组非法私钥(也许更多组),但是该非法私钥的计算过程仍然依赖素因子P和Q,也就是没有绕过大数分解难题,对RSA算法的安全性没有任何影响(不过非法私钥比合法私钥小很多,暴力破解的话也许会在时间复杂度上小很多)。
而且对于用户来说,密钥一旦生成,不论是合法私钥还是非法私钥,在加解密、签名验签的过程中均没有任何正确性的影响,那么也许我们不能说这个密钥就是非法的,它只是不满足E * D ≡ 1 % φ(N)这一个条件罢了,其他的完全没有影响啊!
最后要说的是我提到的检测软件为什么会得到这么一组非法私钥的原因(我验证得知,该工具给出的私钥全部都是非法的,不知道为什么还用了很多年),可能性有两个:
一、
如上所述,在计算φ(N)的时候错误的使用了最小公倍数的算法((P - 1)和(Q - 1)都约掉2的时候,计算出来的并不是最小公倍数),导致计算得到的并不是期望的φ(N),所以会导致后面私钥的计算非法。
二、
DP = D % (P - 1)
DQ = D % (Q - 1)
则,在补全秘钥的时候,没有考虑到(P - 1)和(Q - 1)实际并不互素,却强制使用了中国剩余定理,导致计算出非法私钥,当然了这个本质上跟可能性一是一样的。
就此,问题解决。
==============================2017.01.23晨更新==============================
非常感谢评论区@Mike_Dog的评论,使用他的方法,已经可以求解出下面文章中的非法私钥,且可以求出来不止一个。
现在手机码字不是很方便,等我分析一下,晚上做更新!
==============================2017.01.22更新==============================
非常感谢大家的关注和编辑的推荐!
按照我之前的猜测,结合大家的回复,我目前的主要验证点集中在验证P和Q两个大数是否确定是素数上。
如之前的原文中所说,这两个数我进行了多次Robin-Miller素数检测,且之前的重复次数为5次,现在我将重复次数增加到20次,检测结果依然是素数。
不过这个检测方式和费马检测一样,都是概率性检测,尽管20次重复,P和Q确实是素数的概率已经非常非常高了,但是仍然有极低的概率可能不是素数。
如果这个猜想成立的话,那么想必这两个数中应该至少有一个是卡迈克尔数(Carmichael Number),那么就不得不考虑一个100%能够确认的方式进行素性检测了。
我前天使用了穷举的方式尝试暴力检测,使用P对2~sqrt(P)依次取余,看是否有能够除尽的因子。但是我没有考虑该方式的时间复杂度,两天两夜的时间只计算到0x1C09AC7F75。
这个方式已经就此打住了,因为我的电脑风扇要像疯狗一样算几辈子才能得到我想要的结果。。。
现在在考虑的是印度的Manindra Agrawal教授和他的两个学生Neeraj Kayal和Nitin Saxena共同开发的AKS素数检测算法,可以保证100%的确认。
这个算法非常新颖,非常有趣,但是原理理解起来有些困难。
希望我能尽快理解并实现该算法,得出相应的结论。
针对该算法,如果有大牛比较熟悉,也希望能指点一下,多谢!
==============================以下是原文==============================
笔者从事各种数据加解密算法相关的工作若干年,今天要说的是基于大数分解难题的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 确实是素数。其他可行的方案,也希望有相关知识的大牛指点一二,不吝赐教,小可不胜感激。
本人邮箱:[email protected]