RSA - 仅使用(!)模数加密?

Posted

技术标签:

【中文标题】RSA - 仅使用(!)模数加密?【英文标题】:RSA - Encrypting using only(!) Modulus? 【发布时间】:2017-01-25 14:32:30 【问题描述】:

我们正在使用另一家公司的 API。 在那个 API 中,我应该使用 RSACryptoServiceProvider 生成一个密钥对并发送公钥,以便他们可以为我们加密数据。

这不是问题。在他们的 API 中 - 公钥是 byte[] 类型。

所以我想这样做:

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
var pubKey = rsa.ToXmlString(false); //only public

然后,将其表示为byte[]

var ValuetoSend = Encoding.UTF8.GetBytes(pubKey);

并发送该值。

但他们回应了:

“您应该只向我们提供RSAKeyInfo 中的Modulus 属性 信息”

所以我想知道,这可能吗?他们可以只使用 Modulus 加密数据吗?

所以我创建了一个测试:(请注意My CodeTheir code

   //My Code
    byte[] data_clear = UTF8Encoding.UTF8.GetBytes("hellowא");
    var rsa = new RSACryptoServiceProvider(1024);
    var MyModulus = rsa.ExportParameters(true).Modulus;



    //Their code ( I assume , If they only want MyModulus)
    var rsa2 =   new RSACryptoServiceProvider(1024);
    var rsa2Params = rsa2.ExportParameters(true);
    rsa2Params.Modulus=MyModulus;  //they set their Modulus to MY Modulus
    byte[] enc_data = rsa2.Encrypt(data_clear, true);

  // Back to my code


    var g=Encoding.UTF8.GetString( rsa.Decrypt(enc_data, true));
    Console.WriteLine(g);

结果: 例外:

解码 OAEP 填充时发生 CryptographicException 错误。

问题

1) 他们是否可以仅使用 Modulus 进行加密?

2) 如果是这样,我的测试出了什么问题,我该如何解决。

编辑 - 即使我添加了 exponenet ,它也会失败:

   //My Code
    byte[] data_clear = UTF8Encoding.UTF8.GetBytes("hellowא");
    var rsa = new RSACryptoServiceProvider(1024);
    var MyModulus = rsa.ExportParameters(true).Modulus;
    var MyExponent = rsa.ExportParameters(true).Exponent;



    //Their code ( I assume , If they only want MyModulus)
    var rsa2 =   new RSACryptoServiceProvider(1024);
    var rsa2Params = rsa2.ExportParameters(true);
    rsa2Params.Modulus=MyModulus;  //they set their Modulus to MY Modulus
    rsa2Params.Exponent=MyExponent;  //they set their Modulus to MY Modulus
    byte[] enc_data = rsa2.Encrypt(data_clear, true);



   // Back to my code
    var g=Encoding.UTF8.GetString( rsa.Decrypt(enc_data, true));
    Console.WriteLine(g); 

   //CryptographicException Error occurred while decoding OAEP padding.

【问题讨论】:

我认为他们需要模数和指数。这里有些东西似乎很狡猾。 @EricLippert 你好,埃里克。即使我提供指数,it failes 模数类型密钥的公共部分(私钥=所有因素分开),但没有指数就没有用,不是吗? @ManfredRadlwimmer 对他们来说没用是的 - 但他们不需要解密(我应该这样做)。我确实有私钥。但这不是我的问题。如您所见,即使我有私钥和公钥,它也无法解密数据(仅当他们使用模块时)。 正如@EricLippert 所说,您需要模数和指数。这样做的原因是几乎所有 RSA 密钥都使用 F4 (0x010001) 的固定指数。随着您执行 ExportParameters,覆盖 Modulus,然后执行 ImportParameters,您只是保留了现有的 Exponent 值,这可能是他们在接收端所做的事情。公钥操作是paddedMessage^Exponent % Modulus,所以肯定需要指数:)。 【参考方案1】:

好的,事情就是这样。

似乎在最后一行中设置了新值:

var rsa2 =   new RSACryptoServiceProvider(2048);  
var rsa2Params = rsa2.ExportParameters(false);
rsa2Params.Modulus=MyModulus; //they set their Modulus to MY Modulus

rsa2 对象并不真正可见,因为 RSAParameters 是一个结构。

所以我们需要rsa2导入该结构。

我添加了这一行:

rsa2.ImportParameters(rsa2Params);

另外 - 肯定需要一个指数。那么,如果没有我为他们提供指数,它怎么能在他们这边工作呢?好吧,这是因为当今世界指数的默认值(0x010001)。所以这就是他们可以加密的原因

不管怎样,现在一切正常:

【讨论】:

【参考方案2】:

1) 模数和指数是加密所必需的。也用于查找对应的私钥进行解密。

2)您没有在RSACryptoServiceProvider中设置私钥,因此您无法解密字节数组。

【讨论】:

关于2,我这边的私钥确实存在。在他们这边,它没有。他们只需要加密 请检查您的私钥内容,如果您使用的私钥正确,则私钥的模数和指数应与您的公钥相同。 他们是。我知道。我只是不知道指数的默认值(我没有提供给他们)。 ,所以不明白没有 exp 部分如何加密。

以上是关于RSA - 仅使用(!)模数加密?的主要内容,如果未能解决你的问题,请参考以下文章

加密大于 RSA 密钥(模数)大小的数据。将拆分的数据加密成块,似乎不起作用。有任何想法吗?

Java中的RSA加密/解密

RSA:在给定公钥的情况下获取指数和模数

在 PHP 中使用 RSA 加密和解密文本

RSA加密输出大小

.NET 中的 RSA 加密/解密问题