【问题标题】:.NET Core 3.1 - RSA.ImportRSAPrivateKey raises a CryptographicException.NET Core 3.1 - RSA.ImportRSAPrivateKey 引发 CryptographicException
【发布时间】:2021-04-14 15:53:53
【问题描述】:

我正在训练使用 RSA 进行非对称加密。我用 ssh-keygen 创建了一个密钥对,并设法用我的公钥加密了一些数据。 但是当我尝试用我的私钥解密这些数据时,就会引发这个异常:

System.Security.Cryptography.CryptographicException : 'ASN1 corrupted data.'

这是我的 PEM 文件,其中包含我的私钥:

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,E79376C1ECFD82F05A871D9245BFC958

iEL9aNdWIC3TckveRH2ADdHrnCAQeyg0GUFx0obx1sHOCDdiCIb2u46vFUQ8QP6H
vHHgA9Kf4lY8Jq6Qkv/Iyhh9WcWTR2nNjbN7Ndlb343MyjeNdlXdVrHsfR8Q98ul
06FiKZdnS640PzxAUvibbmkLVus8g3V14qZqeDTqN1rbOCAk2Kxfy5V4kd6M7wCm
fqABkYpp+2EYf4Z4YcJbLDXEEIg7HD/AI1gPpE5nRQoSib/9bm87j98VnG5dOYAJ
38ZMTvJjIImQveOUeSNyR/re71V+YUy0N/zvqMrlp4pDFsDb6infZga0jPFzGXGy
5S3XYXSs9iPReFHQnhWr/L3dRx9TpfZJcl4BJ6D8j9wxrWRcharGNNgCK/kV9FJw
BpwFu01jNESDHV3dyWTcOAzQit4pDkr0A9EK4N1vfWaLLO8vqyGtqlvtU5sD2rYQ
JvrMEsUsAYXJcBDUX2cksNEen+7s338cBGg4NdE+xAUeKv5EysYIKgojPJi6WQ39
FAgkr1TfWaffO/TgfL/DwC1wyHXleNyDQ87unyxRIRu/wWnqJaQQG8Z0BilIbDp8
KrKfkHW9CWaPCbldOzHJ5UDZmA5+AvfoaATRw/vW1Wg0GYkuNqqHzV7tNFKcnUG1
DmIaSI+Y55cngqeOStFfgRTehbXK84w3PzR3lnpuxG4rtOjDV8RfZSozaSValqju
ZWRYEbKn7Za2XZWJT4kkDa5O4nJUMbihBOUL+FWc6dmDIaZY/nUKJAm2pxmd0R1s
9PcXhqLEnBTvGh1CrOdhiqkHQ5A5OtIp/FrPhUltjsy129NC5/dPZaN9v4TgNYQu
zNd8vSlVXuimB+2OoXu3fNE75ywxmrs4H8M4y3u87GQWFdYwQFFnv2fyCzV8iqvy
ybQR599v5qL2IKvHdw68q9PDmasd4jSTAoFP/g6QQKMCaQuMUbrtlHzvPvNnCgk1
AChbFeuLK57c2rwVwTx0YEATcKz27/V5af0E2x6sLDoqQv5SBkREuuWyA6DsSO/S
vX1WR/hZWk2PVi24N/AG8T/sIfyBeTPw7Yx3RuT5MWLdR6haSEKkGGrGuxr1HnoF
lt3JruZczavGpAn5Q8DSVKb78Q8kqI/gdLYNIuq5Yy7Mz1ldocN0N2CarUGWgU7e
+z0TM2CWkTBE7Q0CU4Na5QusvaLYDgH4LW4WY9BNN86C4uKQFjJHz6gZoI3zx8/L
RxN2bGyd0H83k4xuQXml2RnnPPB6L5JwJxxme5ecWpMdp5c6xyXX1ZPKkkGuRbFs
OxeQqNNfPEExqtC2U/Jn5B1HYJqCYCeKlUNdqUoZv5vT8x9UDoE5vKtP3DtTckeB
+6n7S2viNWzV2qid8moh9DfWGMlF4i1y91pdcNJx+M01OfLOB1EPlD0MoTvkfU6s
x0VQh5t4wCbcJ7kcIrp2siPbBg4RPV8MNKtaBhTvFf+nH1TAEsUMjdi7FrnfBn3b
4o4BqC+ibQHC/+SkGAxRakdJjM5XcXO1BZp4zLYSBQyXGu7kp8ohOvHx65vtwvls
XCdbtnJs/iAORxAgLnuVPzLUfTd6bLlszOsyIvC8+j587GX5YFW+h4s+bicZMwCm
-----END RSA PRIVATE KEY-----

这是使用此私钥的代码示例:

static string RSA_Decrypt(byte[] value)
{
    byte[] deciphered;

    using (var reader = File.OpenText(@"C:\Users\???\.ssh\id_rsa"))
    {
        // Extracting the payload
        string privateKeyFile = reader.ReadToEnd();
        var exp = privateKeyFile.Split("\n\n");
        var privateKey = exp[1].Split("\n-----")[0];

        // using the payload to decrypt my data
        using(var rsa = RSA.Create())
        {
            rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _); //CryptographicException

            deciphered = rsa.Decrypt(value, RSAEncryptionPadding.Pkcs1);
        }
    }

    return Encoding.Default.GetString(deciphered);
}

我做错了什么?

【问题讨论】:

    标签: c# encryption .net-core rsa


    【解决方案1】:

    发布的私钥是 PEM 编码的 PKCS#1 密钥,已加密。

    RSA.ImportRSAPrivateKey() 只能导入这种格式的未加密密钥,而且还经过 DER 编码。 DER 编码来自 PEM 编码,去除页眉和页脚,Base64 解码其余部分。

    据我所知,无法使用 .NET Core 3.1 板载方式导入加密的 PKCS#1 密钥。但是可以使用BouncyCastle 及其Org.BouncyCastle.OpenSsl.PemReader 类进行导入,请参见例如here.

    与 PKCS#1 格式不同,PKCS#8 格式的 DER 编码私钥可以使用 .NET Core 3.1 开箱即用 (RSA.ImportPkcs8PrivateKey()) 导入,即使它已加密 (RSA.ImportEncryptedPkcs8PrivateKey())。 可以生成这种格式的密钥,例如与openssl genpkey。使用 OpenSSL 还可以在格式之间进行转换。

    【讨论】:

      【解决方案2】:

      感谢 Topaco,这正是我所需要的!我使用 BouncyCastle 解密了我的私钥,现在它运行良好!我不知道为什么 RSA 类没有任何方法可以做到这一点...

      现在这是我的代码:

      static string RSA_Decrypt(byte[] value)
      {
          string deciphered;
      
          using (var reader = File.OpenText(@"C:\Users\???\.ssh\id_rsa"))
          {
              string privateKeyFile = reader.ReadToEnd();
              var keyReader = new StringReader(privateKeyFile);
      
              var decryptEngine = new Pkcs1Encoding(new RsaEngine());
      
              object pemReader = new PemReader(keyReader, new PasswordFinder("azerty")).ReadObject();
              var keyPair = (AsymmetricCipherKeyPair)pemReader;
              decryptEngine.Init(false, keyPair.Private);
      
              deciphered = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(value, 0, value.Length));
          }
      
          return deciphered;
      }
      

      PS : 是的,我的私钥密码是“azerty”^^ 创建密钥对时我没有受到启发 ^^

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多