<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" />

PublicKeyFactory

public static class PublicKeyFactory
using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.Cryptlib; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.EdEC; using Org.BouncyCastle.Asn1.Gnu; using Org.BouncyCastle.Asn1.Oiw; using Org.BouncyCastle.Asn1.Pkcs; using Org.BouncyCastle.Asn1.Rosstandart; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Math; using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Utilities; using System; using System.IO; namespace Org.BouncyCastle.Security { public static class PublicKeyFactory { public static AsymmetricKeyParameter CreateKey(byte[] keyInfoData) { return CreateKey(SubjectPublicKeyInfo.GetInstance(keyInfoData)); } public static AsymmetricKeyParameter CreateKey(Stream inStr) { return CreateKey(SubjectPublicKeyInfo.GetInstance(Asn1Object.FromStream(inStr))); } public static AsymmetricKeyParameter CreateKey(SubjectPublicKeyInfo keyInfo) { AlgorithmIdentifier algorithm = keyInfo.Algorithm; DerObjectIdentifier algorithm2 = algorithm.Algorithm; if (algorithm2.Equals(PkcsObjectIdentifiers.RsaEncryption) || algorithm2.Equals(X509ObjectIdentifiers.IdEARsa) || algorithm2.Equals(PkcsObjectIdentifiers.IdRsassaPss) || algorithm2.Equals(PkcsObjectIdentifiers.IdRsaesOaep)) { RsaPublicKeyStructure instance = RsaPublicKeyStructure.GetInstance(keyInfo.ParsePublicKey()); return new RsaKeyParameters(false, instance.Modulus, instance.PublicExponent); } if (algorithm2.Equals(X9ObjectIdentifiers.DHPublicNumber)) { Asn1Sequence instance2 = Asn1Sequence.GetInstance(algorithm.Parameters.ToAsn1Object()); BigInteger value = DHPublicKey.GetInstance(keyInfo.ParsePublicKey()).Y.Value; if (IsPkcsDHParam(instance2)) return ReadPkcsDHParam(algorithm2, value, instance2); DHDomainParameters instance3 = DHDomainParameters.GetInstance(instance2); BigInteger value2 = instance3.P.Value; BigInteger value3 = instance3.G.Value; BigInteger value4 = instance3.Q.Value; BigInteger j = null; if (instance3.J != null) j = instance3.J.Value; DHValidationParameters validation = null; DHValidationParms validationParms = instance3.ValidationParms; if (validationParms != null) { byte[] bytes = validationParms.Seed.GetBytes(); BigInteger value5 = validationParms.PgenCounter.Value; validation = new DHValidationParameters(bytes, value5.IntValue); } return new DHPublicKeyParameters(value, new DHParameters(value2, value3, value4, j, validation)); } if (algorithm2.Equals(PkcsObjectIdentifiers.DhKeyAgreement)) { Asn1Sequence instance4 = Asn1Sequence.GetInstance(algorithm.Parameters.ToAsn1Object()); DerInteger derInteger = (DerInteger)keyInfo.ParsePublicKey(); return ReadPkcsDHParam(algorithm2, derInteger.Value, instance4); } if (algorithm2.Equals(OiwObjectIdentifiers.ElGamalAlgorithm)) { ElGamalParameter instance5 = ElGamalParameter.GetInstance(algorithm.Parameters); return new ElGamalPublicKeyParameters(((DerInteger)keyInfo.ParsePublicKey()).Value, new ElGamalParameters(instance5.P, instance5.G)); } if (algorithm2.Equals(X9ObjectIdentifiers.IdDsa) || algorithm2.Equals(OiwObjectIdentifiers.DsaWithSha1)) { DerInteger obj = (DerInteger)keyInfo.ParsePublicKey(); Asn1Encodable parameters = algorithm.Parameters; DsaParameters parameters2 = null; if (parameters != null) { DsaParameter instance6 = DsaParameter.GetInstance(parameters.ToAsn1Object()); parameters2 = new DsaParameters(instance6.P, instance6.Q, instance6.G); } return new DsaPublicKeyParameters(obj.Value, parameters2); } if (algorithm2.Equals(X9ObjectIdentifiers.IdECPublicKey)) { ECDomainParameters eCDomainParameters = ECDomainParameters.FromX962Parameters(X962Parameters.GetInstance(algorithm.Parameters)); ECPoint q = eCDomainParameters.Curve.DecodePoint(keyInfo.PublicKey.GetBytes()); return new ECPublicKeyParameters("EC", q, eCDomainParameters); } if (algorithm2.Equals(CryptoProObjectIdentifiers.GostR3410x2001)) { DerObjectIdentifier publicKeyParamSet = Gost3410PublicKeyAlgParameters.GetInstance(algorithm.Parameters).PublicKeyParamSet; X9ECParameters byOid = ECGost3410NamedCurves.GetByOid(publicKeyParamSet); if (byOid == null) return null; Asn1OctetString asn1OctetString; try { asn1OctetString = (Asn1OctetString)keyInfo.ParsePublicKey(); } catch (IOException innerException) { throw new ArgumentException("error recovering GOST3410_2001 public key", innerException); } int num = 32; int num2 = 2 * num; byte[] octets = asn1OctetString.GetOctets(); if (octets.Length != num2) throw new ArgumentException("invalid length for GOST3410_2001 public key"); byte[] array = new byte[1 + num2]; array[0] = 4; for (int i = 1; i <= num; i++) { array[i] = octets[num - i]; array[i + num] = octets[num2 - i]; } ECPoint q2 = byOid.Curve.DecodePoint(array); return new ECPublicKeyParameters("ECGOST3410", q2, publicKeyParamSet); } if (algorithm2.Equals(CryptoProObjectIdentifiers.GostR3410x94)) { Gost3410PublicKeyAlgParameters instance7 = Gost3410PublicKeyAlgParameters.GetInstance(algorithm.Parameters); Asn1OctetString asn1OctetString2; try { asn1OctetString2 = (Asn1OctetString)keyInfo.ParsePublicKey(); } catch (IOException innerException2) { throw new ArgumentException("error recovering GOST3410_94 public key", innerException2); } byte[] octets2 = asn1OctetString2.GetOctets(); return new Gost3410PublicKeyParameters(new BigInteger(1, octets2, false), instance7.PublicKeyParamSet); } if (algorithm2.Equals(EdECObjectIdentifiers.id_X25519) || algorithm2.Equals(CryptlibObjectIdentifiers.curvey25519)) return new X25519PublicKeyParameters(GetRawKey(keyInfo)); if (algorithm2.Equals(EdECObjectIdentifiers.id_X448)) return new X448PublicKeyParameters(GetRawKey(keyInfo)); if (algorithm2.Equals(EdECObjectIdentifiers.id_Ed25519) || algorithm2.Equals(GnuObjectIdentifiers.Ed25519)) return new Ed25519PublicKeyParameters(GetRawKey(keyInfo)); if (algorithm2.Equals(EdECObjectIdentifiers.id_Ed448)) return new Ed448PublicKeyParameters(GetRawKey(keyInfo)); if (algorithm2.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256) || algorithm2.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) || algorithm2.Equals(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_256) || algorithm2.Equals(RosstandartObjectIdentifiers.id_tc26_agreement_gost_3410_12_512)) { Gost3410PublicKeyAlgParameters instance8 = Gost3410PublicKeyAlgParameters.GetInstance(algorithm.Parameters); DerObjectIdentifier publicKeyParamSet2 = instance8.PublicKeyParamSet; ECGost3410Parameters eCGost3410Parameters = new ECGost3410Parameters(new ECNamedDomainParameters(publicKeyParamSet2, ECGost3410NamedCurves.GetByOid(publicKeyParamSet2)), publicKeyParamSet2, instance8.DigestParamSet, instance8.EncryptionParamSet); Asn1OctetString asn1OctetString3; try { asn1OctetString3 = (Asn1OctetString)keyInfo.ParsePublicKey(); } catch (IOException innerException3) { throw new ArgumentException("error recovering GOST3410_2012 public key", innerException3); } int num3 = 32; if (algorithm2.Equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512)) num3 = 64; int num4 = 2 * num3; byte[] octets3 = asn1OctetString3.GetOctets(); if (octets3.Length != num4) throw new ArgumentException("invalid length for GOST3410_2012 public key"); byte[] array2 = new byte[1 + num4]; array2[0] = 4; for (int k = 1; k <= num3; k++) { array2[k] = octets3[num3 - k]; array2[k + num3] = octets3[num4 - k]; } return new ECPublicKeyParameters(eCGost3410Parameters.Curve.DecodePoint(array2), eCGost3410Parameters); } if (MLDsaParameters.ByOid.TryGetValue(algorithm2, out MLDsaParameters value6)) return GetMLDsaPublicKey(value6, keyInfo.PublicKey); if (MLKemParameters.ByOid.TryGetValue(algorithm2, out MLKemParameters value7)) return GetMLKemPublicKey(value7, keyInfo.PublicKey); if (SlhDsaParameters.ByOid.TryGetValue(algorithm2, out SlhDsaParameters value8)) return GetSlhDsaPublicKey(value8, keyInfo.PublicKey); throw new SecurityUtilityException("algorithm identifier in public key not recognised: " + algorithm2?.ToString()); } internal static MLDsaPublicKeyParameters GetMLDsaPublicKey(MLDsaParameters mlDsaParameters, DerBitString publicKey) { if (publicKey.IsOctetAligned()) { int publicKeyLength = mlDsaParameters.ParameterSet.PublicKeyLength; int bytesLength = publicKey.GetBytesLength(); if (bytesLength == publicKeyLength) return MLDsaPublicKeyParameters.FromEncoding(mlDsaParameters, publicKey.GetOctets()); if (bytesLength > publicKeyLength) try { Asn1OctetString asn1OctetString = Asn1Object.FromMemoryStream(publicKey.GetOctetMemoryStream()) as Asn1OctetString; if (asn1OctetString != null && asn1OctetString.GetOctetsLength() == publicKeyLength) return MLDsaPublicKeyParameters.FromEncoding(mlDsaParameters, asn1OctetString.GetOctets()); } catch (Exception) { } } throw new ArgumentException("invalid " + mlDsaParameters.Name + " public key"); } internal static MLKemPublicKeyParameters GetMLKemPublicKey(MLKemParameters mlKemParameters, DerBitString publicKey) { if (publicKey.IsOctetAligned()) { int publicKeyLength = mlKemParameters.ParameterSet.PublicKeyLength; if (publicKey.GetBytesLength() == publicKeyLength) return MLKemPublicKeyParameters.FromEncoding(mlKemParameters, publicKey.GetOctets()); } throw new ArgumentException("invalid " + mlKemParameters.Name + " public key"); } private static byte[] GetRawKey(SubjectPublicKeyInfo keyInfo) { return keyInfo.PublicKey.GetOctets(); } internal static SlhDsaPublicKeyParameters GetSlhDsaPublicKey(SlhDsaParameters slhDsaParameters, DerBitString publicKey) { if (publicKey.IsOctetAligned()) { int publicKeyLength = slhDsaParameters.ParameterSet.PublicKeyLength; int bytesLength = publicKey.GetBytesLength(); if (bytesLength == publicKeyLength) return SlhDsaPublicKeyParameters.FromEncoding(slhDsaParameters, publicKey.GetOctets()); if (bytesLength > publicKeyLength) try { Asn1OctetString asn1OctetString = Asn1Object.FromMemoryStream(publicKey.GetOctetMemoryStream()) as Asn1OctetString; if (asn1OctetString != null && asn1OctetString.GetOctetsLength() == 4 + publicKeyLength) { byte[] octets = asn1OctetString.GetOctets(); byte[] encoding = Arrays.CopyOfRange(octets, 4, octets.Length); return SlhDsaPublicKeyParameters.FromEncoding(slhDsaParameters, encoding); } } catch (Exception) { } } throw new ArgumentException("invalid " + slhDsaParameters.Name + " public key"); } private static bool IsPkcsDHParam(Asn1Sequence seq) { if (seq.Count == 2) return true; if (seq.Count > 3) return false; DerInteger instance = DerInteger.GetInstance(seq[2]); DerInteger instance2 = DerInteger.GetInstance(seq[0]); return instance.Value.CompareTo(BigInteger.ValueOf(instance2.Value.BitLength)) <= 0; } private static DHPublicKeyParameters ReadPkcsDHParam(DerObjectIdentifier algOid, BigInteger y, Asn1Sequence seq) { DHParameter instance = DHParameter.GetInstance(seq); int l = instance.L?.IntValue ?? 0; DHParameters parameters = new DHParameters(instance.P, instance.G, null, l); return new DHPublicKeyParameters(y, parameters, algOid); } } }