private void KeyFormatters_PrivateKeyRoundTrip(RSAParameters initialValue, CryptographicPrivateKeyBlobType format) { this.logger.WriteLine("Generated RSA parameters:"); this.LogRSAParameters(initialValue, " "); var formatter = KeyFormatter.GetFormatter(format); byte[] custom = formatter.Write(initialValue); var rsaParametersRead = formatter.Read(custom); this.logger.WriteLine("Read RSA parameters:"); this.LogRSAParameters(rsaParametersRead, " "); Assert.Equal <byte>(initialValue.Exponent, rsaParametersRead.Exponent); Assert.Equal <byte>(initialValue.Modulus, rsaParametersRead.Modulus); Assert.Equal <byte>(initialValue.P, rsaParametersRead.P); Assert.Equal <byte>(initialValue.Q, rsaParametersRead.Q); if (format != CryptographicPrivateKeyBlobType.BCryptPrivateKey) { Assert.Equal <byte>(initialValue.D, rsaParametersRead.D); Assert.Equal <byte>(initialValue.DP, rsaParametersRead.DP); Assert.Equal <byte>(initialValue.DQ, rsaParametersRead.DQ); Assert.Equal <byte>(initialValue.InverseQ, rsaParametersRead.InverseQ); } else { // BCryptPrivateKey is lossy, by design. Assert.Null(rsaParametersRead.D); Assert.Null(rsaParametersRead.DP); Assert.Null(rsaParametersRead.DQ); Assert.Null(rsaParametersRead.InverseQ); } }
public void KeyPairInterop(CryptographicPrivateKeyBlobType blobType, AsymmetricAlgorithm algorithmName, string base64Key) { var algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName); var key = algorithm.ImportKeyPair(Convert.FromBase64String(base64Key), blobType); var p1 = KeyFormatter.GetFormatter(blobType).Read(Convert.FromBase64String(base64Key)); string exported = Convert.ToBase64String(key.Export(blobType)); var p2 = KeyFormatter.GetFormatter(blobType).Read(Convert.FromBase64String(exported)); this.LogRSAParameterComparison("Original", p1, "Re-exported", p2); if (blobType == CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo && exported.Length == base64Key.Length - 20) { // I'm not sure what the last 20 bytes are (perhaps the optional attributes) // But Windows platforms produces them and Android doesn't seem to. // Since the private key material seems to be elsewhere, we'll exclude // the suffix from the comparison. // The prefix is also mismatched, but that seems to also be ignorable. Assert.Equal(base64Key.Substring(6, exported.Length - 6), exported.Substring(6)); } else { // This check tends to be too brittle to implementation details of the native crypto, // which may re-encode the D parameter for reasons I don't understand. ////Assert.Equal(base64Key, exported); // The two prime numbers are really all that matter. Assert.Equal <byte>(p1.P, p2.P); Assert.Equal <byte>(p1.Q, p2.Q); } }
/// <inheritdoc/> public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType = CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); RSAParameters parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); // Inject the PKCS#1 public key into the KeyChain. string keyIdentifier = Guid.NewGuid().ToString(); string publicKeyIdentifier = RsaCryptographicKey.GetPublicKeyIdentifierWithTag(keyIdentifier); var keyQueryDictionary = RsaCryptographicKey.CreateKeyQueryDictionary(publicKeyIdentifier); keyQueryDictionary[KSec.ValueData] = NSData.FromArray(KeyFormatter.Pkcs1.Write(parameters, includePrivateKey: false)); keyQueryDictionary[KSec.AttrKeyClass] = KSec.AttrKeyClassPublic; keyQueryDictionary[KSec.ReturnRef] = NSNumber.FromBoolean(true); IntPtr resultHandle; int status = RsaCryptographicKey.SecItemAdd(keyQueryDictionary.Handle, out resultHandle); if (resultHandle != IntPtr.Zero) { var key = new SecKey(resultHandle, true); return(new RsaCryptographicKey(key, keyIdentifier, this.Algorithm)); } else { throw new InvalidOperationException("SecItemAdd return " + status); } }
/// <inheritdoc /> public byte[] ExportPublicKey(CryptographicPublicKeyBlobType blobType) { byte[] keyData = KeyDataWithTag(GetPublicKeyIdentifierWithTag(this.keyIdentifier)).ToArray(); RSAParameters parameters = KeyFormatter.Pkcs1.Read(keyData); return(KeyFormatter.GetFormatter(blobType).Write(parameters)); }
/// <inheritdoc/> public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType = CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); var rsa = new Platform.RSACryptoServiceProvider(); rsa.ImportParameters(KeyFormatter.ToPlatformParameters(KeyFormatter.GetFormatter(blobType).Read(keyBlob))); return(new RsaCryptographicKey(rsa, this.algorithm)); }
/// <inheritdoc/> public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType = CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); var parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); var spec = new RSAPublicKeySpec(new BigInteger(1, parameters.Modulus), new BigInteger(1, parameters.Exponent)); KeyFactory factory = KeyFactory.GetInstance("RSA"); IPublicKey publicKey = factory.GeneratePublic(spec); return(new RsaCryptographicKey(publicKey, parameters, this.algorithm)); }
/// <inheritdoc /> public byte[] Export(CryptographicPrivateKeyBlobType blobType) { try { return(KeyFormatter.GetFormatter(blobType).Write(KeyFormatter.ToPCLParameters(this.key.ExportParameters(true)))); } catch (CryptographicException ex) { throw new InvalidOperationException("Private key not available.", ex); } }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); RSAParameters parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); string keyIdentifier = Guid.NewGuid().ToString(); SecKey privateKey = ImportKey(parameters, RsaCryptographicKey.GetPrivateKeyIdentifierWithTag(keyIdentifier)); SecKey publicKey = ImportKey(KeyFormatter.PublicKeyFilter(parameters), RsaCryptographicKey.GetPublicKeyIdentifierWithTag(keyIdentifier)); return(new RsaCryptographicKey(publicKey, privateKey, keyIdentifier, this.Algorithm)); }
/// <inheritdoc/> public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType) { Requires.NotNull(keyBlob, "keyBlob"); using (var provider = NCryptOpenStorageProvider(KeyStorageProviders.MS_KEY_STORAGE_PROVIDER)) { byte[] bcryptPublicBlob = blobType == this.NativePublicKeyFormatEnum ? keyBlob : KeyFormatter.GetFormatter(this.NativePublicKeyFormatEnum).Write(KeyFormatter.GetFormatter(blobType).Read(keyBlob)); var key = NCryptImportKey(provider, null, this.NativePublicKeyFormatString, IntPtr.Zero, bcryptPublicBlob); return(this.CreateKey(key, isPublicOnly: true)); } }
static KeyFormatterTests() { rsaParameters = new Lazy <RSAParameters>(() => { var algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha1); using (var key = algorithm.CreateKeyPair(512)) { const CryptographicPrivateKeyBlobType keyBlobFormat = CryptographicPrivateKeyBlobType.BCryptFullPrivateKey; byte[] bcryptNative = key.Export(keyBlobFormat); var rsaParameters = KeyFormatter.GetFormatter(keyBlobFormat).Read(bcryptNative); return(rsaParameters); } }); }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, nameof(keyBlob)); RSAParameters parameters = KeyFormatter.GetFormatter(blobType) .Read(keyBlob) .ComputeFullPrivateKeyData(); IPrivateKey? privateKey = null; IPublicKey? publicKey = null; BigInteger? modulus = null, d = null, publicExponent = null; RSAPrivateKeySpec?privateKeySpec = null; RSAPublicKeySpec? publicKeySpec = null; try { #pragma warning disable CA2000 // Dispose objects before losing scope modulus = new BigInteger(1, parameters.Modulus); d = new BigInteger(1, parameters.D); privateKeySpec = new RSAPrivateKeySpec(modulus, d); var factory = KeyFactory.GetInstance("RSA"); if (factory is null) { throw new InvalidOperationException(Strings.UnsupportedAlgorithm); } privateKey = factory.GeneratePrivate(privateKeySpec) !; var privateRsaKey = privateKey.JavaCast <IRSAPrivateKey>() !; publicExponent = new BigInteger(1, parameters.Exponent); publicKeySpec = new RSAPublicKeySpec(privateRsaKey.Modulus, publicExponent); publicKey = factory.GeneratePublic(publicKeySpec) !; return(new RsaCryptographicKey(publicKey, privateKey, parameters, this.algorithm)); #pragma warning restore CA2000 // Dispose objects before losing scope } catch { publicExponent?.Dispose(); publicKeySpec?.Dispose(); privateKeySpec?.Dispose(); modulus?.Dispose(); d?.Dispose(); privateKey?.Dispose(); publicKey?.Dispose(); throw; } }
/// <inheritdoc /> public override byte[] Export(CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Verify.Operation(!this.IsPublicOnly, "Only public key is available."); try { byte[] nativeBlob; string nativeFormatString; CryptographicPrivateKeyBlobType nativeBlobType; if (this.Provider.NativePrivateKeyFormats.TryGetValue(blobType, out nativeFormatString)) { nativeBlobType = blobType; } else { nativeBlobType = this.Provider.PreferredNativePrivateKeyFormat; nativeFormatString = this.Provider.NativePrivateKeyFormats[nativeBlobType]; } #if NET40 nativeBlob = NCryptExportKey(this.Key, SafeKeyHandle.Null, nativeFormatString, IntPtr.Zero).ToByteArray(); #else nativeBlob = NCryptExportKey(this.Key, SafeKeyHandle.Null, nativeFormatString, IntPtr.Zero).ToArray(); #endif byte[] formattedBlob; if (nativeBlobType != blobType) { var parameters = KeyFormatter.GetFormatter(nativeBlobType).Read(nativeBlob); formattedBlob = KeyFormatter.GetFormatter(blobType).Write(parameters); } else { formattedBlob = nativeBlob; } return(formattedBlob); } catch (SecurityStatusException ex) { if (ex.NativeErrorCode == SECURITY_STATUS.NTE_NOT_SUPPORTED) { throw new NotSupportedException(ex.Message, ex); } throw; } }
public void KeyFormatters_PublicKeyRoundTrip(CryptographicPublicKeyBlobType format) { var formatter = KeyFormatter.GetFormatter(format); byte[] custom = formatter.Write(rsaParameters.Value, includePrivateKey: false); var rsaParametersRead = formatter.Read(custom); Assert.Equal <byte>(rsaParameters.Value.Exponent, rsaParametersRead.Exponent); Assert.Equal <byte>(rsaParameters.Value.Modulus, rsaParametersRead.Modulus); Assert.Null(rsaParametersRead.D); Assert.Null(rsaParametersRead.P); Assert.Null(rsaParametersRead.Q); Assert.Null(rsaParametersRead.DP); Assert.Null(rsaParametersRead.DQ); Assert.Null(rsaParametersRead.InverseQ); }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); RSAParameters parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); IPrivateKey privateKey; IPublicKey publicKey; var spec = new RSAPrivateKeySpec(new BigInteger(1, parameters.Modulus), new BigInteger(1, parameters.D)); var factory = KeyFactory.GetInstance("RSA"); privateKey = factory.GeneratePrivate(spec); var privateRsaKey = privateKey.JavaCast <IRSAPrivateKey>(); var publicKeySpec = new RSAPublicKeySpec(privateRsaKey.Modulus, new BigInteger(1, parameters.Exponent)); publicKey = factory.GeneratePublic(publicKeySpec); return(new RsaCryptographicKey(publicKey, privateKey, parameters, this.algorithm)); }
/// <inheritdoc /> public override byte[] ExportPublicKey(CryptographicPublicKeyBlobType blobType) { try { byte[] nativeBlob = NCryptExportKey(this.Key, SafeKeyHandle.Null, this.Provider.NativePublicKeyFormatString, IntPtr.Zero).ToArray(); byte[] formattedBlob = blobType == this.Provider.NativePublicKeyFormatEnum ? nativeBlob : KeyFormatter.GetFormatter(blobType).Write(KeyFormatter.GetFormatter(this.Provider.NativePublicKeyFormatEnum).Read(nativeBlob)); return(formattedBlob); } catch (SecurityStatusException ex) { if (ex.NativeErrorCode == SECURITY_STATUS.NTE_NOT_SUPPORTED) { throw new NotSupportedException(ex.Message, ex); } throw; } }
/// <inheritdoc /> public byte[] Export(CryptographicPrivateKeyBlobType blobType) { NSData data = KeyDataWithTag(GetPrivateKeyIdentifierWithTag(this.keyIdentifier)); Verify.Operation(data != null, "Private key not available."); byte[] keyData; try { keyData = data.ToArray(); } catch (ArgumentNullException ex) { // MonoTouch throws this when the private key is missing. throw new InvalidOperationException("Private key not available.", ex); } var parameters = KeyFormatter.Pkcs1.Read(keyData); return(KeyFormatter.GetFormatter(blobType).Write(parameters)); }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); var parameters = KeyFormatter.GetFormatter(blobType) .Read(keyBlob) .ComputeFullPrivateKeyData(); if (!CapiKeyFormatter.IsCapiCompatible(parameters)) { // Try to make it CAPI compatible since it's faster on desktop, // and the only thing that could possibly work on wp8. RSAParameters adjustedParameters = KeyFormatter.NegotiateSizes(parameters); if (CapiKeyFormatter.IsCapiCompatible(adjustedParameters)) { parameters = adjustedParameters; } } Platform.RSA rsa; if (CapiKeyFormatter.IsCapiCompatible(parameters)) { rsa = new Platform.RSACryptoServiceProvider(); } else { #if DESKTOP rsa = new RSAManaged(); #else // Throw the exception explaining the problem. CapiKeyFormatter.VerifyCapiCompatibleParameters(parameters); // Make it obvious to the compiler that the buck stops here. // er... on the line above. throw new NotSupportedException(); #endif } rsa.ImportParameters(KeyFormatter.ToPlatformParameters(parameters)); return(new RsaCryptographicKey(rsa, this.algorithm)); }
public void Pkcs1DecodingTest() { #pragma warning disable 0436 // Initialize the "Known Good" RSAParameters. byte[] capi1Blob = Convert.FromBase64String(AsymmetricKeyAlgorithmProviderTests.Helper.PrivateKeyFormatsAndBlobs[Tuple.Create(PCLCrypto.AsymmetricAlgorithm.RsaOaepSha1, CryptographicPrivateKeyBlobType.Capi1PrivateKey)]); var rsa = new RSACryptoServiceProvider(); rsa.ImportCspBlob(capi1Blob); RSAParameters rsaCapi = rsa.ExportParameters(true); // Now load up the tested one. byte[] pkcs1KeyBlob = Convert.FromBase64String(AsymmetricKeyAlgorithmProviderTests.Helper.PrivateKeyFormatsAndBlobs[Tuple.Create(PCLCrypto.AsymmetricAlgorithm.RsaOaepSha1, CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey)]); RSAParameters homeReadPkcs1 = KeyFormatter.ToPlatformParameters(KeyFormatter.GetFormatter(CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey).Read(pkcs1KeyBlob)); #pragma warning restore 0436 Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.Modulus), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.Modulus)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.Exponent), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.Exponent)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.D), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.D)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.P), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.P)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.Q), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.Q)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.DP), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.DP)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.DQ), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.DQ)); Assert.Equal(WinRTCrypto.CryptographicBuffer.EncodeToHexString(rsaCapi.InverseQ), WinRTCrypto.CryptographicBuffer.EncodeToHexString(homeReadPkcs1.InverseQ)); }
/// <inheritdoc/> public ICryptographicKey ImportPublicKey(byte[] keyBlob, CryptographicPublicKeyBlobType blobType = CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo) { Requires.NotNull(keyBlob, nameof(keyBlob)); var parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); BigInteger? modulus = null, exponent = null; RSAPublicKeySpec?spec = null; try { #pragma warning disable CA2000 // Dispose objects before losing scope modulus = new BigInteger(1, parameters.Modulus); exponent = new BigInteger(1, parameters.Exponent); spec = new RSAPublicKeySpec(modulus, exponent); #pragma warning restore CA2000 // Dispose objects before losing scope KeyFactory?factory = KeyFactory.GetInstance("RSA"); if (factory is null) { throw new InvalidOperationException(Strings.UnsupportedAlgorithm); } IPublicKey?publicKey = factory.GeneratePublic(spec); if (publicKey is null) { throw new InvalidOperationException("KeyFactory.GeneratePublic returned null."); } return(new RsaCryptographicKey(publicKey, parameters, this.algorithm)); } catch { spec?.Dispose(); modulus?.Dispose(); exponent?.Dispose(); throw; } }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); using (var provider = NCryptOpenStorageProvider(KeyStorageProviders.MS_KEY_STORAGE_PROVIDER)) { byte[] bcryptPrivateBlob; string nativeFormatString; if (this.NativePrivateKeyFormats.TryGetValue(blobType, out nativeFormatString)) { bcryptPrivateBlob = keyBlob; } else { var parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); bcryptPrivateBlob = KeyFormatter.GetFormatter(this.PreferredNativePrivateKeyFormat).Write(parameters); nativeFormatString = this.NativePrivateKeyFormats[this.PreferredNativePrivateKeyFormat]; } var key = NCryptImportKey(provider, null, nativeFormatString, IntPtr.Zero, bcryptPrivateBlob); NCryptSetProperty(key, KeyStoragePropertyIdentifiers.NCRYPT_EXPORT_POLICY_PROPERTY, 3); return(this.CreateKey(key, isPublicOnly: false)); } }
/// <inheritdoc/> public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo) { Requires.NotNull(keyBlob, "keyBlob"); var parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob); Platform.RSA rsa; if (CapiKeyFormatter.IsCapiCompatible(parameters)) { rsa = new Platform.RSACryptoServiceProvider(); } else { #if DESKTOP rsa = new RSAManaged(); #else CapiKeyFormatter.VerifyCapiCompatibleParameters(parameters); throw new NotSupportedException(); #endif } rsa.ImportParameters(KeyFormatter.ToPlatformParameters(parameters)); return(new RsaCryptographicKey(rsa, this.algorithm)); }
/// <inheritdoc /> public byte[] ExportPublicKey(CryptographicPublicKeyBlobType blobType) { return(KeyFormatter.GetFormatter(blobType).Write(KeyFormatter.ToPCLParameters(this.key.ExportParameters(false)))); }
/// <inheritdoc /> public byte[] Export(CryptographicPrivateKeyBlobType blobType) { Verify.Operation(KeyFormatter.HasPrivateKey(this.parameters), "Private key not available."); return(KeyFormatter.GetFormatter(blobType).Write(this.parameters)); }
/// <inheritdoc /> public byte[] ExportPublicKey(CryptographicPublicKeyBlobType blobType) { return(KeyFormatter.GetFormatter(blobType).Write(this.parameters, includePrivateKey: false)); }