【问题标题】:phpseclib rsa decryption return falsephpseclib rsa 解密返回 false
【发布时间】:2017-08-26 21:10:51
【问题描述】:

我正在尝试为 c# 服务器和网站实现公私钥加密/解密。如果我使用 PHP 上的公钥加密,我可以使用私钥轻松解密它,但是当我使用公钥加密 C# 中的数据时,我无法使用 PHP 上的私钥对其进行解密。基本上,什么都不返回(或从 var_dump 中返回 false)。

C#

var pkey = $"<RSAKeyValue>\r\n\t<Modulus>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsaxzQmdhvuM+yjJJgpVHUr0DW 3XbAr/sWbSdceanVX7IhccU8XCGurrM7rNYWhyIBzD8/RGGnqupfdt3rsNYvMKMO rU6thBEDBUVYJO58olDgW7ACbd/u95/0uRPzwGeqDQUn565iDfMyU6+jjaoGn7+D 5D0Bt8x6mLiu43y0zQIDAQAB</Modulus>\r\n\t<Exponent>AQAB</Exponent>\r\n</RSAKeyValue>";

//Encrypting the text using the public key
cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(pkey);
byte[] data = Encoding.UTF8.GetBytes(message);
byte[] cipherText = cipher.Encrypt(data, false);
var encrypted = Convert.ToBase64String(cipherText);
Console.WriteLine(encrypted);

C# code image

来自 PHP

$rsa = new RSA();
$rsa->loadKey('MIICXQIBAAKBgQCsaxzQmdhvuM+yjJJgpVHUr0DW3XbAr/sWbSdceanVX7IhccU8/nXCGurrM7rNYWhyIBzD8/RGGnqupfdt3rsNYvMKMOrU6thBEDBUVYJO58olDgW7AC/nbd/u95/0uRPzwGeqDQUn565iDfMyU6+jjaoGn7+D5D0Bt8x6mLiu43y0zQIDAQAB/nAoGAXLIRgczUYew4LcQJhlAbGH9IGrxh9eIm2b3BZaQ7PG4AdJ6X7YWSzjk6PyEC/n0IXCMLlAX6FB50SqULy1PtuJql6HAGP5E1YLUxbgct/+JTC3Txy7jLlBRENyf4Nz/nj0oVvR+//vLLNc/MRl4g8gsCOvtTv4QWDkhvPYq0nLNkGHkCQQDkdiGs103RC5pf/n9/SUMq95bIpAS3jDOrjNKrHjTCYPzchExh1Q3qcyJWWCDgUVP4rUwk5NBYyJ/Glb/nRUDeXuQbAkEAwTOag7BbRguTjjcZeyHrbCPEaimpEClzdEWp6CPxGwHYcTWes74K/ncJrhesgy3ZTqVi4lILdNbpUvq1JjvwpJNwJAVplYxnWOb7EgQURyF0LnNPWpqhlx/nmz9FEbAfYfNZciAky7z1G9RqOB3ozlWWI6nEbEWC/LsfvKZLIWes4R3DBQJBAJq3/nOmtu1Qj4yEdA9JTYivDki6wAhLS+nQhlqTSPY8se5Tdzmw2RiEa4oQx0OdecIzS0/na2MRp16A9dWaeupH0G0CQQDii6l2MeVK4ImBqeEjycRQYRhRxLsiEA7ad0ptGvfC/nir/AowGmQ6jTmkMxp+zSFFCHS8ZHAAcBnZ3Ef5kA8SFY');
$convert = base64_decode("CkR7GLQZFUHLcFnhMGxsLYX/4rbrOM+NaXFLyTED3H+xbTChLsXRBQTGo7Xme44b4+/1c7SWahah/FI4gqFx5aDJ1olUmvUR/cto2X7QjBbIBJiFmXRAokbyyBBZ14v8iFqHwunv6Yc+5k/kO/fMK41mJn8xQms+K79CERkCASB7W3dxAFqh06Ksq/Mi9HwW0RakIsbHsdhu3hGQQy4d4h5J");
var_dump($rsa->decrypt($convert));

注意:这些密钥不是真实的,它们是为开发目的而生成的

Link to testing environment code

【问题讨论】:

  • 确保使用正确的填充方案和散列函数进行加密和填充方案。
  • 您能说得更具体些吗?我使用了两种语言提供的关于实现的教程。
  • 在我看来,php 和 c# 中的公钥是不同的
  • @vSugumar 我用 c# 代码中的图像编辑了帖子。基本上忽略了括号之间的所有内容。其他在 c# 中是公钥,在 PHP 中是密钥

标签: c# php encryption rsa phpseclib


【解决方案1】:

错误的填充方案

您必须使用完全相同的填充方案才能工作。

cipher.Encrypt(data, false) 中的 false 禁用 OAEP。因此,PKCS#1 v1.5 填充将用于加密。

您必须设置以下内容才能使用相同的填充方案:

$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);

钥匙坏了

请记住,您需要为此使用正确的密钥。您似乎正在使用来自 here 的密钥进行测试。

如果我们decode 公钥,我们会得到十六进制:

modulus = 94 FB 56 CB 7C F9 9C 63 BA AB 17  F7 53 6C 0B 6E 26 5B F8 47 F1 55 73 55 84 1F D1  CA 53 48 D0 8D 7F E7 FD D6 FD BF 3F F1 D2 2D ED  7B F6 CA 2C D1 1C C1 48 41 BB E3 D6 3E 73 AD FE  A5 54 44 6F 41 51 3E 91 B0 24 45 52 7D 02 C8 68  94 2A 8C B8 E6 8F 4A FE 62 40 1E 66 EB 36 DA D4  07 A7 24 AD 82 C5 EF 96 39 D2 75 0D B0 15 47 50  3C 3C C9 0C A6 9A 23 81 4F 58 1C FC A3 39 B3 5C  53 CF 8E 0B 33
exponent = 01 00 01

我们可以使用this tool 将此十六进制表示转换为 Base64 表示。请记住,如果您想转换它,请不要传输您的私钥。您的 C# 公钥如下所示:

<RSAKeyValue><Modulus>lPtWy3z5nGO6qxf3U2wLbiZb+EfxVXNVhB/RylNI0I1/5/3W/b8/8dIt7Xv2yizRHMFIQbvj1j5zrf6lVERvQVE+kbAkRVJ9AsholCqMuOaPSv5iQB5m6zba1AenJK2Cxe+WOdJ1DbAVR1A8PMkMppojgU9YHPyjObNcU8+OCzM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

现在到您的私钥。 PHP supports multiline strings。使用它们!您试图将您的私钥减少到一行,因此,您犯了一个错误。换行符是 \n 而不是 /n。

解决方案

C# example:

var pkey = "<RSAKeyValue><Modulus>lPtWy3z5nGO6qxf3U2wLbiZb+EfxVXNVhB/RylNI0I1/5/3W/b8/8dIt7Xv2yizRHMFIQbvj1j5zrf6lVERvQVE+kbAkRVJ9AsholCqMuOaPSv5iQB5m6zba1AenJK2Cxe+WOdJ1DbAVR1A8PMkMppojgU9YHPyjObNcU8+OCzM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

var cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(pkey);
byte[] data = Encoding.UTF8.GetBytes("some message");
byte[] cipherText = cipher.Encrypt(data, false);
var encrypted = Convert.ToBase64String(cipherText);
Console.WriteLine(encrypted);

C# 输出:

 kryqst55mqwmjq0n1gbxopaomvng / bdnwk / 0s2g4cqskd1fm7ktfdqivngly6kbpxy0unwzghbbpugraloiteyphcrdsgigvuc2o0lqi74qroloyoshxwx7tyawzljb6yivshxwpy / 6wj5xkhlzrju9kxmfribgob9 + b2x6c4a =  pre>

PHP 示例:

use \phpseclib\Crypt\RSA;

$private_key = "-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCU+1bLfPmcY7qrF/dTbAtuJlv4R/FVc1WEH9HKU0jQjX/n/db9vz/x0i3te/bK
LNEcwUhBu+PWPnOt/qVURG9BUT6RsCRFUn0CyGiUKoy45o9K/mJAHmbrNtrUB6ckrYLF75Y50nUN
sBVHUDw8yQymmiOBT1gc/KM5s1xTz44LMwIDAQABAoGAGsiMtAyFu23ac0PdvOuhqm3O/vXAF0Ki
zxwBVURfxM6LfiOOcRPe5RSKGTW+Cl7AQVEmMlsa/LtBhLhQ9LNQ5L/4oTmRhCGiZZEmccAdjKsx
yMeaxkp+ZHvMxMKQNDgYg1CXqrCrpwwUuMUlA26tfxZ3xSFtFyDTaV9mgDQ1IGECQQCkX9Tum7D1
vQTwbhbYnu7eC4eUOaZeGWSEs2csK7U6vfZ3BzUZW/0tPqcSpQqcNxMtY9TiUsNRj1uM6jX3byp7
AkEA6Ab+wvOTNRtES77OAYG9gHGZZ+iXjQJ/6Z7JehN4p41UbDIf9nNUOLUPL9z5V1uOYnl1CWoo
Cw95cdhKXxEAqQJBAIU5Or6tp250ZdVslM27ewSyuY9UblfkIsk/EscFIdzbbDAqwkmsefW6yvTc
mU3lgYCPYlKRG8c19tCuX1ENY5MCQAz37x9YW975Ai01ofAFn2DheJCNOINCI4IcROiU1AaRaKmP
d6fftFJjFFE5iZovXNr2LOt0yn4rxD7vtuBvY9kCQGyty6YCB6qaD7qXPMhLrLbGajAIWd6ETgxv
frK/BJu+buPfDky/g1FhI5R9iMtL1xH0JYLJlaVocU+xSeA9DkY=
-----END RSA PRIVATE KEY-----";

$rsa = new RSA();
var_dump($rsa->loadKey($private_key));
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$convert = base64_decode("kRyQsT55mQWmjQ0n1GbXOpaoMvng/BDNWk/0S2G4cqsKD1Fm7ktFdQIvnGlY6kbPXY0unwzGHbBpUGrALOITeyPHCRdsGIGVUc2O0lqI74QROloyoShXwX7TyAwzLJB6yiVSM7SDpy/6wJ5XkHLZRJu9KxmFrIBgOB9+b2x6C4A=");
var_dump($rsa->decrypt($convert));

PHP 输出:

布尔(真)
string(12) "一些信息"

【讨论】:

  • 遗憾的是上面不起作用。它返回空/假响应。你想在 Github 上设置一个测试环境吗?我想提一下,我的网络环境是 Laravel 5.4,composer 安装了 phpseclib 2.4 版本
  • 我无法进一步帮助您,因为我没有安装 PHP,甚至没有配置 phpseclib。
  • 我试图解析你的私钥。它似乎不是一个有效的私钥。它不能被解析为 ASN.1。
  • 感谢您的努力。我使用了从 phpseclib 生成的私有(也是公共)密钥,其中的空白被 /n 替换,否则您将得到解密错误。From here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2015-06-24
  • 2022-01-12
  • 1970-01-01
  • 2012-10-25
相关资源
最近更新 更多