【问题标题】:C# BouncyCastle FIPS RSA keys to RSACryptoServiceProviderRSACryptoServiceProvider 的 C# BouncyCastle FIPS RSA 密钥
【发布时间】:2021-10-24 01:43:11
【问题描述】:

BouncyCastle 有用于 C# 的 FIPS DLLs,由于合规性,我需要将其用于加密而不是普通的 DLL。您如何导入公钥和私钥并将它们转换为RSACryptoServiceProvider 以进行加密和解密。


这就是我使用常规 BouncyCastle 加密和解密的方式。我只需要更改函数ImportPrivateKeyImportPublicKey

public static string Decrypt(string privateKey, string base64Encrypted)
{
    string ret = null;
    using (var rsa = ImportPrivateKey(privateKey))
    {
        var cipherBytes = Convert.FromBase64String(base64Encrypted);
        RSA rsaCng = new RSACng();
        rsaCng.ImportParameters(rsa.ExportParameters(true));
        byte[] plainBytes = rsaCng.Decrypt(cipherBytes, RSAEncryptionPadding.OaepSHA256);
        string plaintext = Encoding.UTF8.GetString(plainBytes);
        ret = plaintext;
    }
    return ret;
}
public static string Encrypt(string publicKey, string toEncrypt)
{
    string cipherText = null;
    using (var rsa = ImportPublicKey(publicKey))
    {
        var data = Encoding.UTF8.GetBytes(toEncrypt);
        RSA rsaCng = new RSACng();
        rsaCng.ImportParameters(rsa.ExportParameters(false));
        byte[] cipherTextBytes = rsaCng.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
        cipherText = Convert.ToBase64String(cipherTextBytes);
    }
    return cipherText;
}
public RSACryptoServiceProvider ImportPrivateKey(string pem)
{
    PemReader pr = new PemReader(new StringReader(pem));
    AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.ImportParameters(rsaParams);
    return rsa;
}
public RSACryptoServiceProvider ImportPublicKey(string pem)
{
    PemReader pr = new PemReader(new StringReader(pem));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.ImportParameters(rsaParams);
    return rsa;
}

【问题讨论】:

    标签: c# .net rsa bouncycastle public-key-encryption


    【解决方案1】:

    这是我如何让它工作的。如果其他人有更简单的东西那就太棒了!导入密钥将它们转换为AsymmetricRsaPublicKey,然后将它们转换为RSAParameters,然后导入它们。

    using System.IO;
    using System.Security.Cryptography;
    using Org.BouncyCastle.Asn1.X509;
    using Org.BouncyCastle.Crypto.Asymmetric;
    using Org.BouncyCastle.Crypto.Fips;
    using Org.BouncyCastle.OpenSsl;
    
    public RSACryptoServiceProvider ImportPublicKey(string key)
    {
        var reader = new OpenSslPemReader(new StringReader(key));
        var publicKeyInfo = (SubjectPublicKeyInfo)reader.ReadObject();
        var rpckp = new AsymmetricRsaPublicKey(FipsRsa.Pkcs1v15.Algorithm, publicKeyInfo);
        RSAParameters parms = new RSAParameters
        {
            Modulus = rpckp.Modulus.ToByteArrayUnsigned(),
            Exponent = rpckp.PublicExponent.ToByteArrayUnsigned()
        };
        RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider();
        rcsp.ImportParameters(parms);
        return rcsp;
    }
    
    public RSACryptoServiceProvider ImportPrivateKey(string key)
    {
        var reader = new OpenSslPemReader(new StringReader(key));
        var keyPair = (PemKeyPair)reader.ReadObject();
        var rpckp = new AsymmetricRsaPrivateKey(FipsRsa.Pkcs1v15.Algorithm, keyPair.PrivateKeyInfo);
        RSAParameters parms = new RSAParameters
        {
            Modulus = rpckp.Modulus.ToByteArrayUnsigned(),
            P = rpckp.P.ToByteArrayUnsigned(),
            Q = rpckp.Q.ToByteArrayUnsigned(),
            DP = rpckp.DP.ToByteArrayUnsigned(),
            DQ = rpckp.DQ.ToByteArrayUnsigned(),
            InverseQ = rpckp.QInv.ToByteArrayUnsigned(),
            D = rpckp.PrivateExponent.ToByteArrayUnsigned(),
            Exponent = rpckp.PublicExponent.ToByteArrayUnsigned()
        };
        RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider();
        rcsp.ImportParameters(parms);
        return rcsp;
    }
    

    【讨论】:

    • 在单元测试中偶尔会出错,所以在我的代码中,我在生成密钥时添加了一个带有 try/catch 的循环,以确保如果导入不起作用,则会生成新密钥。 /跨度>
    猜你喜欢
    • 2020-12-26
    • 2015-03-21
    • 2014-01-09
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 2012-06-02
    相关资源
    最近更新 更多