private static GostKeyExchangeParameters DecodePublicBlob(byte[] encodedPublicBlob, GostAlgorithmType algorithm) { if (encodedPublicBlob == null) { throw ExceptionUtility.ArgumentNull("encodedPublicBlob"); } int size; switch (algorithm) { case GostAlgorithmType.Gost2001: size = 512; break; case GostAlgorithmType.Gost2012_256: size = 512; break; case GostAlgorithmType.Gost2012_512: size = 1024; break; default: throw new CryptographicException(Resources.AlgorithmNotAvailable); } if (encodedPublicBlob.Length < 16 + size / 8) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var gostKeyMask = BitConverter.ToUInt32(encodedPublicBlob, 8); if (gostKeyMask != Constants.GR3410_1_MAGIC) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var gostKeySize = BitConverter.ToUInt32(encodedPublicBlob, 12); if (gostKeySize != size) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var publicKeyParameters = new GostKeyExchangeParameters(); var encodeKeyParameters = new byte[(encodedPublicBlob.Length - 16) - size / 8]; Array.Copy(encodedPublicBlob, 16, encodeKeyParameters, 0, (encodedPublicBlob.Length - 16) - size / 8); publicKeyParameters.DecodeParameters(encodeKeyParameters); var publicKey = new byte[64]; Array.Copy(encodedPublicBlob, encodedPublicBlob.Length - size / 8, publicKey, 0, size / 8); publicKeyParameters.PublicKey = publicKey; return(publicKeyParameters); }
public static AsymmetricAlgorithm GetPublicKeyAlgorithm(this X509Certificate2 certificate) { if (certificate == null) { throw ExceptionUtility.ArgumentNull("certificate"); } var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(certificate.PublicKey.EncodedParameters.RawData); cspObject.DecodePublicKey(certificate.PublicKey.EncodedKeyValue.RawData); var cspBlobData = CryptoApiHelper.EncodePublicBlob(cspObject); var publicKey = new Gost3410AsymmetricAlgorithm(); publicKey.ImportCspBlob(cspBlobData); return(publicKey); }
private static GostKeyExchangeParameters DecodePublicBlob(byte[] encodedPublicBlob) { if (encodedPublicBlob == null) { throw ExceptionUtility.ArgumentNull("encodedPublicBlob"); } if (encodedPublicBlob.Length < 80) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var gostKeyMask = BitConverter.ToUInt32(encodedPublicBlob, 8); if (gostKeyMask != Constants.GR3410_1_MAGIC) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var gostKeySize = BitConverter.ToUInt32(encodedPublicBlob, 12); if (gostKeySize != 512) { throw ExceptionUtility.CryptographicException(Constants.NTE_BAD_DATA); } var publicKeyParameters = new GostKeyExchangeParameters(); var encodeKeyParameters = new byte[(encodedPublicBlob.Length - 16) - 64]; Array.Copy(encodedPublicBlob, 16, encodeKeyParameters, 0, (encodedPublicBlob.Length - 16) - 64); publicKeyParameters.DecodeParameters(encodeKeyParameters); var publicKey = new byte[64]; Array.Copy(encodedPublicBlob, encodedPublicBlob.Length - 64, publicKey, 0, 64); publicKeyParameters.PublicKey = publicKey; return(publicKeyParameters); }
/// <summary> /// Разбор BLOB открытого ключа ГОСТ 34.10. /// </summary> /// /// <param name="obj">Gost3410CspObject</param> /// <param name="data">BLOB</param> /// <param name="alg">Тип алгоритма</param> /// /// <argnull name="obj" /> /// <exception cref="CryptographicException">Если /// <paramref name="obj"/> не объект типа /// <see cref="Gost3410CspObject"/></exception> /// /// <intdoc><para>Аналог в MS отсутствует, часть реализации /// присутствует в ImportKey. </para></intdoc> /// /// <unmanagedperm action="LinkDemand" /> internal static void DecodePublicBlob(Object obj, byte[] data, CspAlgorithmType alg) { int keySize; switch (alg) { case CspAlgorithmType.PROV_GOST_2001_DH: keySize = GostConstants.GOST_3410EL_SIZE; break; case CspAlgorithmType.PROV_GOST_2012_256: keySize = GostConstants.GOST3410_2012_256KEY_SIZE; break; case CspAlgorithmType.PROV_GOST_2012_512: keySize = GostConstants.GOST3410_2012_512KEY_SIZE; break; default: throw new CryptographicException(SR.Cryptography_CSP_WrongKeySpec); } if (obj == null) { throw new ArgumentNullException("obj"); } Gost3410CspObject cspObject = obj as Gost3410CspObject; if (cspObject == null) { throw new CryptographicException(GostConstants.NTE_BAD_ALGID); } if (data.Length < 16 + keySize / 8) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } // CRYPT_PUBKEYPARAM -> 8 { Magic, BitLen ) uint magic = BitConverter.ToUInt32(data, 8); uint bitlen = BitConverter.ToUInt32(data, 12); if (magic != GostConstants.GR3410_1_MAGIC) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } if (bitlen != keySize) { throw new CryptographicException(GostConstants.NTE_BAD_DATA); } byte[] tmp = new byte[data.Length - 16 - keySize / 8]; Array.Copy(data, 16, tmp, 0, data.Length - 16 - keySize / 8); var publicKeyParameters = new GostKeyExchangeParameters(); var encodeKeyParameters = new byte[(data.Length - 16) - keySize / 8]; Array.Copy(data, 16, encodeKeyParameters, 0, (data.Length - 16) - keySize / 8); publicKeyParameters.DecodeParameters(encodeKeyParameters); var publicKey = new byte[keySize / 8]; Array.Copy(data, data.Length - keySize / 8, publicKey, 0, keySize / 8); publicKeyParameters.PublicKey = publicKey; cspObject._publicKey = publicKeyParameters.PublicKey; cspObject._publicKeyParamSet = publicKeyParameters.PublicKeyParamSet; cspObject._digestParamSet = publicKeyParameters.DigestParamSet; }
public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.EcPublicKey && certificatePal != null) { return(DecodeECDsaPublicKey((CertificatePal)certificatePal)); } int algId = Interop.Crypt32.FindOidInfo(CryptOidInfoKeyType.CRYPT_OID_INFO_OID_KEY, oid.Value, OidGroup.PublicKeyAlgorithm, fallBackToAllGroups: true).AlgId; switch (algId) { case AlgId.CALG_RSA_KEYX: case AlgId.CALG_RSA_SIGN: { byte[] keyBlob = DecodeKeyBlob(CryptDecodeObjectStructType.CNG_RSA_PUBLIC_KEY_BLOB, encodedKeyValue); CngKey cngKey = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob); return(new RSACng(cngKey)); } //begin: gost case AlgId.CALG_GOST3410: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410CryptoServiceProvider gost_sp = new Gost3410CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } case AlgId.CALG_GOST3410_2012_256: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410_2012_256CryptoServiceProvider gost_sp = new Gost3410_2012_256CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } case AlgId.CALG_GOST3410_2012_512: { var cspObject = new GostKeyExchangeParameters(); cspObject.DecodeParameters(encodedParameters); cspObject.DecodePublicKey(encodedKeyValue, algId); var cspBlobData = GostKeyExchangeParameters.EncodePublicBlob(cspObject, algId); Gost3410_2012_512CryptoServiceProvider gost_sp = new Gost3410_2012_512CryptoServiceProvider(); gost_sp.ImportCspBlob(cspBlobData); return(gost_sp); } //end: gost case AlgId.CALG_DSS_SIGN: { byte[] keyBlob = ConstructDSSPublicKeyCspBlob(encodedKeyValue, encodedParameters); DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(keyBlob); return(dsa); } default: throw new NotSupportedException(SR.NotSupported_KeyAlgorithm); } }