DotNetUtilities
A class containing methods to interface the BouncyCastle world to the .NET Crypto world.
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.X509;
using System;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
namespace Org.BouncyCastle.Security
{
public static class DotNetUtilities
{
public static System.Security.Cryptography.X509Certificates.X509Certificate ToX509Certificate(X509CertificateStructure x509Struct)
{
return new System.Security.Cryptography.X509Certificates.X509Certificate(x509Struct.GetDerEncoded());
}
public static System.Security.Cryptography.X509Certificates.X509Certificate ToX509Certificate(Org.BouncyCastle.X509.X509Certificate x509Cert)
{
return new System.Security.Cryptography.X509Certificates.X509Certificate(x509Cert.GetEncoded());
}
public static Org.BouncyCastle.X509.X509Certificate FromX509Certificate(System.Security.Cryptography.X509Certificates.X509Certificate x509Cert)
{
return new X509CertificateParser().ReadCertificate(x509Cert.GetRawCertData());
}
public static AsymmetricCipherKeyPair GetDsaKeyPair(DSA dsa)
{
return GetDsaKeyPair(dsa.ExportParameters(true));
}
public static AsymmetricCipherKeyPair GetDsaKeyPair(DSAParameters dp)
{
DsaPublicKeyParameters dsaPublicKey = GetDsaPublicKey(dp);
DsaPrivateKeyParameters privateParameter = new DsaPrivateKeyParameters(new BigInteger(1, dp.X), dsaPublicKey.Parameters);
return new AsymmetricCipherKeyPair(dsaPublicKey, privateParameter);
}
public static DsaPublicKeyParameters GetDsaPublicKey(DSA dsa)
{
return GetDsaPublicKey(dsa.ExportParameters(false));
}
public static DsaPublicKeyParameters GetDsaPublicKey(DSAParameters dp)
{
DsaValidationParameters parameters = (dp.Seed != null) ? new DsaValidationParameters(dp.Seed, dp.Counter) : null;
DsaParameters parameters2 = new DsaParameters(new BigInteger(1, dp.P), new BigInteger(1, dp.Q), new BigInteger(1, dp.G), parameters);
return new DsaPublicKeyParameters(new BigInteger(1, dp.Y), parameters2);
}
public static AsymmetricCipherKeyPair GetECDsaKeyPair(ECDsa ecDsa)
{
return GetECKeyPair("ECDSA", ecDsa.ExportParameters(true));
}
public static ECPublicKeyParameters GetECDsaPublicKey(ECDsa ecDsa)
{
return GetECPublicKey("ECDSA", ecDsa.ExportParameters(false));
}
public static AsymmetricCipherKeyPair GetECKeyPair(string algorithm, ECParameters ec)
{
ECPublicKeyParameters eCPublicKey = GetECPublicKey(algorithm, ec);
ECPrivateKeyParameters privateParameter = new ECPrivateKeyParameters(eCPublicKey.AlgorithmName, new BigInteger(1, ec.D), eCPublicKey.Parameters);
return new AsymmetricCipherKeyPair(eCPublicKey, privateParameter);
}
public static ECPublicKeyParameters GetECPublicKey(string algorithm, ECParameters ec)
{
X9ECParameters x9ECParameters = GetX9ECParameters(ec.Curve);
if (x9ECParameters == null)
throw new NotSupportedException("Unrecognized curve");
return new ECPublicKeyParameters(algorithm, GetECPoint(x9ECParameters.Curve, ec.Q), new ECDomainParameters(x9ECParameters));
}
private static Org.BouncyCastle.Math.EC.ECPoint GetECPoint(Org.BouncyCastle.Math.EC.ECCurve curve, System.Security.Cryptography.ECPoint point)
{
return curve.CreatePoint(new BigInteger(1, point.X), new BigInteger(1, point.Y));
}
private static X9ECParameters GetX9ECParameters(System.Security.Cryptography.ECCurve curve)
{
if (!curve.IsNamed)
throw new NotSupportedException("Only named curves are supported");
Oid oid = curve.Oid;
if (oid != null) {
string value = oid.Value;
if (value != null)
return ECKeyPairGenerator.FindECCurveByOid(new DerObjectIdentifier(value));
}
return null;
}
public static AsymmetricCipherKeyPair GetRsaKeyPair(RSA rsa)
{
return GetRsaKeyPair(rsa.ExportParameters(true));
}
public static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp)
{
RsaKeyParameters rsaPublicKey = GetRsaPublicKey(rp);
RsaPrivateCrtKeyParameters privateParameter = new RsaPrivateCrtKeyParameters(rsaPublicKey.Modulus, rsaPublicKey.Exponent, new BigInteger(1, rp.D), new BigInteger(1, rp.P), new BigInteger(1, rp.Q), new BigInteger(1, rp.DP), new BigInteger(1, rp.DQ), new BigInteger(1, rp.InverseQ));
return new AsymmetricCipherKeyPair(rsaPublicKey, privateParameter);
}
public static RsaKeyParameters GetRsaPublicKey(RSA rsa)
{
return GetRsaPublicKey(rsa.ExportParameters(false));
}
public static RsaKeyParameters GetRsaPublicKey(RSAParameters rp)
{
return new RsaKeyParameters(false, new BigInteger(1, rp.Modulus), new BigInteger(1, rp.Exponent));
}
public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
{
DSA dSA = privateKey as DSA;
if (dSA != null)
return GetDsaKeyPair(dSA);
ECDsa eCDsa = privateKey as ECDsa;
if (eCDsa != null)
return GetECDsaKeyPair(eCDsa);
RSA rSA = privateKey as RSA;
if (rSA != null)
return GetRsaKeyPair(rSA);
throw new ArgumentException("Unsupported algorithm specified", "privateKey");
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaKeyParameters rsaKey)
{
return CreateRSAProvider(ToRSAParameters(rsaKey));
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaKeyParameters rsaKey, CspParameters csp)
{
return CreateRSAProvider(ToRSAParameters(rsaKey), csp);
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey)
{
return CreateRSAProvider(ToRSAParameters(privKey));
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaPrivateCrtKeyParameters privKey, CspParameters csp)
{
return CreateRSAProvider(ToRSAParameters(privKey), csp);
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaPrivateKeyStructure privKey)
{
return CreateRSAProvider(ToRSAParameters(privKey));
}
[SupportedOSPlatform("windows")]
public static RSA ToRSA(RsaPrivateKeyStructure privKey, CspParameters csp)
{
return CreateRSAProvider(ToRSAParameters(privKey), csp);
}
public static RSAParameters ToRSAParameters(RsaKeyParameters rsaKey)
{
RSAParameters rSAParameters = default(RSAParameters);
rSAParameters.Modulus = rsaKey.Modulus.ToByteArrayUnsigned();
if (rsaKey.IsPrivate)
rSAParameters.D = ConvertRSAParametersField(rsaKey.Exponent, rSAParameters.Modulus.Length);
else
rSAParameters.Exponent = rsaKey.Exponent.ToByteArrayUnsigned();
return rSAParameters;
}
public static RSAParameters ToRSAParameters(RsaPrivateCrtKeyParameters privKey)
{
RSAParameters rSAParameters = default(RSAParameters);
rSAParameters.Modulus = privKey.Modulus.ToByteArrayUnsigned();
rSAParameters.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
rSAParameters.P = privKey.P.ToByteArrayUnsigned();
rSAParameters.Q = privKey.Q.ToByteArrayUnsigned();
rSAParameters.D = ConvertRSAParametersField(privKey.Exponent, rSAParameters.Modulus.Length);
rSAParameters.DP = ConvertRSAParametersField(privKey.DP, rSAParameters.P.Length);
rSAParameters.DQ = ConvertRSAParametersField(privKey.DQ, rSAParameters.Q.Length);
rSAParameters.InverseQ = ConvertRSAParametersField(privKey.QInv, rSAParameters.Q.Length);
return rSAParameters;
}
public static RSAParameters ToRSAParameters(RsaPrivateKeyStructure privKey)
{
RSAParameters rSAParameters = default(RSAParameters);
rSAParameters.Modulus = privKey.Modulus.ToByteArrayUnsigned();
rSAParameters.Exponent = privKey.PublicExponent.ToByteArrayUnsigned();
rSAParameters.P = privKey.Prime1.ToByteArrayUnsigned();
rSAParameters.Q = privKey.Prime2.ToByteArrayUnsigned();
rSAParameters.D = ConvertRSAParametersField(privKey.PrivateExponent, rSAParameters.Modulus.Length);
rSAParameters.DP = ConvertRSAParametersField(privKey.Exponent1, rSAParameters.P.Length);
rSAParameters.DQ = ConvertRSAParametersField(privKey.Exponent2, rSAParameters.Q.Length);
rSAParameters.InverseQ = ConvertRSAParametersField(privKey.Coefficient, rSAParameters.Q.Length);
return rSAParameters;
}
private static byte[] ConvertRSAParametersField(BigInteger n, int size)
{
return BigIntegers.AsUnsignedByteArray(size, n);
}
[SupportedOSPlatform("windows")]
private static RSACryptoServiceProvider CreateRSAProvider(RSAParameters rp)
{
CspParameters cspParameters = new CspParameters();
cspParameters.KeyContainerName = $"""{Guid.NewGuid()}";
return CreateRSAProvider(rp, cspParameters);
}
[SupportedOSPlatform("windows")]
private static RSACryptoServiceProvider CreateRSAProvider(RSAParameters rp, CspParameters csp)
{
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(csp);
rSACryptoServiceProvider.ImportParameters(rp);
return rSACryptoServiceProvider;
}
}
}