/// <inheritdoc/>
        public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            var key = CngKey.Import(keyBlob, GetPlatformKeyBlobType(blobType));
            return new CngCryptographicKey(key);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="BCryptRsaKeyFormatter"/> class.
 /// </summary>
 /// <param name="privateKeyType">
 /// Either <see cref="CryptographicPrivateKeyBlobType.BCryptFullPrivateKey"/> or <see cref="CryptographicPrivateKeyBlobType.BCryptPrivateKey"/>
 /// </param>
 public BCryptRsaKeyFormatter(CryptographicPrivateKeyBlobType privateKeyType)
 {
     Requires.Argument(privateKeyType == CryptographicPrivateKeyBlobType.BCryptFullPrivateKey || privateKeyType == CryptographicPrivateKeyBlobType.BCryptPrivateKey, nameof(privateKeyType), "Not a BCrypt key blob format.");
     this.keyType = privateKeyType == CryptographicPrivateKeyBlobType.BCryptFullPrivateKey
         ? BCRYPT_RSAKEY_BLOB.MagicNumber.BCRYPT_RSAFULLPRIVATE_MAGIC
         : BCRYPT_RSAKEY_BLOB.MagicNumber.BCRYPT_RSAPRIVATE_MAGIC;
 }
        /// <inheritdoc/>
        public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            var key = this.platform.ImportKeyPair(keyBlob.ToBuffer(), GetPlatformKeyBlobType(blobType));
            return new CryptographicKey(key);
        }
        /// <inheritdoc />
        public byte[] Export(CryptographicPrivateKeyBlobType blobType)
        {
            try
            {
                if (blobType == CryptographicPrivateKeyBlobType.BCryptPrivateKey && this.eccPrivateKeyBlob != null)
                {
                    // Imported keys are always ephemeral and cannot be exported.
                    // But we can make the API work if we have the private key data.
                    // Copy the key data before returning it to avoid sharing an array
                    // with the caller that would allow the caller to change our key data.
                    return this.eccPrivateKeyBlob.CloneArray();
                }

                return this.key.Export(CngAsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType));
            }
            catch (CryptographicException ex)
            {
                if (ex.IsNotSupportedException())
                {
                    throw new NotSupportedException(ex.Message, ex);
                }

                throw;
            }
        }
示例#5
0
        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);
            }
        }
示例#6
0
        /// <inheritdoc />
        public byte[] Export(CryptographicPrivateKeyBlobType blobType)
        {
            try
            {
                if (blobType == CryptographicPrivateKeyBlobType.BCryptPrivateKey && this.eccPrivateKeyBlob != null)
                {
                    // Imported keys are always ephemeral and cannot be exported.
                    // But we can make the API work if we have the private key data.
                    // Copy the key data before returning it to avoid sharing an array
                    // with the caller that would allow the caller to change our key data.
                    return(this.eccPrivateKeyBlob.CloneArray());
                }

                return(this.key.Export(CngAsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType)));
            }
            catch (CryptographicException ex)
            {
                if (ex.IsNotSupportedException())
                {
                    throw new NotSupportedException(ex.Message, ex);
                }

                throw;
            }
        }
示例#7
0
    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);
        }
    }
示例#8
0
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     try
     {
         return(this.key.Export(AsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType)).ToArray());
     }
     catch (NotImplementedException ex)
     {
         throw new NotSupportedException(ex.Message, ex);
     }
     catch (ArgumentException ex)
     {
         // ArgumentException can be thrown when we don't have the private key,
         // or when the key can't be serialized using the requested format.
         // The first of these deserves an InvalidOperationException while
         // the second one deserves a NotSupportedException. But we can't clearly
         // discern each case from the exception. So we use internal state to assist.
         if (this.canExportPrivateKey)
         {
             // Exporting should work, so it must be an unsupported format.
             throw new NotSupportedException(ex.Message, ex);
         }
         else
         {
             // We can't have been expected to export regardless of the setting.
             throw new InvalidOperationException(ex.Message, ex);
         }
     }
 }
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     try
     {
         return this.key.Export(AsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType)).ToArray();
     }
     catch (NotImplementedException ex)
     {
         throw new NotSupportedException(ex.Message, ex);
     }
     catch (ArgumentException ex)
     {
         // ArgumentException can be thrown when we don't have the private key,
         // or when the key can't be serialized using the requested format.
         // The first of these deserves an InvalidOperationException while
         // the second one deserves a NotSupportedException. But we can't clearly
         // discern each case from the exception. So we use internal state to assist.
         if (this.canExportPrivateKey)
         {
             // Exporting should work, so it must be an unsupported format.
             throw new NotSupportedException(ex.Message, ex);
         }
         else
         {
             // We can't have been expected to export regardless of the setting.
             throw new InvalidOperationException(ex.Message, ex);
         }
     }
 }
        /// <inheritdoc/>
        public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            var key = CngKey.Import(keyBlob, GetPlatformKeyBlobType(blobType));

            return(new CngCryptographicKey(key, blobType == CryptographicPrivateKeyBlobType.BCryptPrivateKey ? keyBlob : null));
        }
示例#11
0
        /// <inheritdoc/>
        public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            var key = this.platform.ImportKeyPair(keyBlob.ToBuffer(), GetPlatformKeyBlobType(blobType));

            return(new CryptographicKey(key));
        }
示例#12
0
    public void PrivateKeyFormat(CryptographicPrivateKeyBlobType format)
    {
        var rsa = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha1);
        var key = rsa.CreateKeyPair(512);

        byte[] serialized = key.Export(format);
        Assert.NotNull(serialized);
        Assert.NotEmpty(serialized);
    }
示例#13
0
 /// <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 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);
     }
 }
示例#15
0
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo)
 {
     try
     {
         return(this.platformKey.Export(blobType.ToPlatformKeyBlobType()).ToArray());
     }
     catch (NotImplementedException ex)
     {
         throw new NotSupportedException(ex.Message, ex);
     }
 }
        /// <summary>
        /// Gets the platform-specific enum value for the given PCL enum value.
        /// </summary>
        /// <param name="blobType">The platform independent enum value for the blob type.</param>
        /// <returns>The platform-specific enum value for the equivalent blob type.</returns>
        internal static CngKeyBlobFormat GetPlatformKeyBlobType(CryptographicPrivateKeyBlobType blobType)
        {
            switch (blobType)
            {
            case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
                return(CngKeyBlobFormat.Pkcs8PrivateBlob);

            default:
                throw new NotSupportedException();
            }
        }
示例#17
0
        /// <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));
        }
示例#18
0
 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);
         }
     });
 }
示例#19
0
 /// <summary>
 /// Gets the formatter to use for a given blob type.
 /// </summary>
 /// <param name="blobType">Type of the key blob.</param>
 /// <returns>An instance of <see cref="KeyFormatter"/></returns>
 internal static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobType)
 {
     switch (blobType)
     {
         case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
             return Pkcs8;
         case CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey:
             return Pkcs1PrependZeros;
         case CryptographicPrivateKeyBlobType.Capi1PrivateKey:
             return Capi;
         default:
             throw new NotSupportedException();
     }
 }
        /// <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;
            }
        }
示例#21
0
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     try
     {
         return(this.key.Export(AsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType)).ToArray());
     }
     catch (NotImplementedException ex)
     {
         throw new NotSupportedException(ex.Message, ex);
     }
     catch (ArgumentException ex)
     {
         throw new InvalidOperationException(ex.Message, ex);
     }
 }
    public void KeyPairRoundTrip(AsymmetricAlgorithm algorithm, int keySize, CryptographicPrivateKeyBlobType format)
    {
        IAsymmetricKeyAlgorithmProvider keyAlgorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithm);

        using (ICryptographicKey key = keyAlgorithm.CreateKeyPair(keySize))
        {
            byte[] keyBlob = key.Export(format);
            using (var key2 = keyAlgorithm.ImportKeyPair(keyBlob, format))
            {
                byte[] key2Blob = key2.Export(format);

                Assert.Equal(Convert.ToBase64String(keyBlob), Convert.ToBase64String(key2Blob));
                this.logger.WriteLine(Convert.ToBase64String(keyBlob));
            }
        }
    }
示例#23
0
        /// <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;
            }
        }
示例#24
0
        /// <summary>
        /// Gets the formatter to use for a given blob type.
        /// </summary>
        /// <param name="blobType">Type of the key blob.</param>
        /// <returns>An instance of <see cref="KeyFormatter"/></returns>
        internal static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobType)
        {
            switch (blobType)
            {
            case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
                return(Pkcs8);

            case CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey:
                return(Pkcs1PrependZeros);

            case CryptographicPrivateKeyBlobType.Capi1PrivateKey:
                return(Capi);

            default:
                throw new NotSupportedException();
            }
        }
        /// <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);
        }
    public void EncryptionInterop(CryptographicPrivateKeyBlobType blobType, AsymmetricAlgorithm algorithmName, string base64Key)
    {
        byte[]            data       = new byte[] { 1, 2, 3 };
        byte[]            cipherText = Convert.FromBase64String("EvnsqTK9tDemRIceCap4Yc5znXeb+nyBPsFRf6oT+OPqQ958RH7NXE3xLKsVJhOLJ4iJ2NM+AlrKRltIK8cTmw==");
        var               algorithm  = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
        ICryptographicKey key        = algorithm.ImportKeyPair(Convert.FromBase64String(base64Key), blobType);

        // Verify that we can decrypt something encrypted previously (on WinRT)
        this.logger.WriteLine("Verify decryption of ciphertext encrypted on WinRT.");
        byte[] decryptedPlaintext = WinRTCrypto.CryptographicEngine.Decrypt(key, cipherText);
        Assert.Equal(Convert.ToBase64String(decryptedPlaintext), Convert.ToBase64String(data));

        // Now verify we can decrypt something we encrypted ourselves.
        this.logger.WriteLine("Verify decryption of ciphertext encrypted on this platform.");
        byte[] myciphertext = WinRTCrypto.CryptographicEngine.Encrypt(key, data);
        byte[] myplaintext  = WinRTCrypto.CryptographicEngine.Decrypt(key, myciphertext);
        Assert.Equal(Convert.ToBase64String(data), Convert.ToBase64String(myplaintext));
    }
        /// <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));
        }
示例#28
0
        /// <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));
        }
    public void KeyPairInterop(CryptographicPrivateKeyBlobType blobType, AsymmetricAlgorithm algorithmName, string base64Key)
    {
        var    algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(algorithmName);
        var    key       = algorithm.ImportKeyPair(Convert.FromBase64String(base64Key), blobType);
        string exported  = Convert.ToBase64String(key.Export(blobType));

        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
        {
            Assert.Equal(base64Key, exported);
        }
    }
        /// <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));
        }
        /// <inheritdoc/>
        public ICryptographicKey ImportKeyPair(byte[] keyBlob, CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo)
        {
            Requires.NotNull(keyBlob, "keyBlob");

            var parameters = KeyFormatter.GetFormatter(blobType).Read(keyBlob);
            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);
        }
        /// <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);
        }
        /// <summary>
        /// Gets the formatter to use for a given blob type.
        /// </summary>
        /// <param name="blobType">Type of the key blob.</param>
        /// <returns>An instance of <see cref="KeyFormatter"/>.</returns>
        public static KeyFormatter GetFormatter(CryptographicPrivateKeyBlobType blobType)
        {
            switch (blobType)
            {
            case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
                return(Pkcs8);

            case CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey:
                return(Pkcs1);

            case CryptographicPrivateKeyBlobType.Capi1PrivateKey:
                return(Capi);

            case CryptographicPrivateKeyBlobType.BCryptPrivateKey:
                return(BCryptRsaPrivateKey);

            case CryptographicPrivateKeyBlobType.BCryptFullPrivateKey:
                return(BCryptRsaFullPrivateKey);

            default:
                throw new NotSupportedException();
            }
        }
        /// <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));
            }
        }
示例#35
0
        /// <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));
        }
示例#36
0
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     Verify.Operation(KeyFormatter.HasPrivateKey(this.parameters), "Private key not available.");
     return KeyFormatter.GetFormatter(blobType).Write(this.parameters);
 }
示例#37
0
        /// <summary>
        /// Gets the platform-specific enum value for the given PCL enum value.
        /// </summary>
        /// <param name="blobType">The platform independent enum value for the blob type.</param>
        /// <returns>The platform-specific enum value for the equivalent blob type.</returns>
        internal static Platform.CryptographicPrivateKeyBlobType GetPlatformKeyBlobType(CryptographicPrivateKeyBlobType blobType)
        {
            switch (blobType)
            {
            case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
                return(Platform.CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo);

            case CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey:
                return(Platform.CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);

            case CryptographicPrivateKeyBlobType.BCryptPrivateKey:
                return(Platform.CryptographicPrivateKeyBlobType.BCryptPrivateKey);

            case CryptographicPrivateKeyBlobType.Capi1PrivateKey:
                return(Platform.CryptographicPrivateKeyBlobType.Capi1PrivateKey);

            default:
                throw new NotSupportedException();
            }
        }
示例#38
0
 public void PrivateKeyFormat(CryptographicPrivateKeyBlobType format)
 {
     var rsa = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaOaepSha1);
     var key = rsa.CreateKeyPair(512);
     byte[] serialized = key.Export(format);
     Assert.NotNull(serialized);
     Assert.NotEmpty(serialized);
 }
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     throw new NotSupportedException();
 }
示例#40
0
        /// <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);
        }
示例#41
0
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     try
     {
         return this.key.Export(AsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType)).ToArray();
     }
     catch (NotImplementedException ex)
     {
         throw new NotSupportedException(ex.Message, ex);
     }
     catch (ArgumentException ex)
     {
         throw new InvalidOperationException(ex.Message, ex);
     }
 }
示例#42
0
		/// <summary>
		/// Exports the key pair to a buffer given a specified format.
		/// </summary>
		/// <param name="BlobType">A CryptographicPrivateKeyBlobType enumeration value that specifies the format of the key in the buffer. The default value is Pkcs8RawPrivateKeyInfo.</param>
		/// <returns>Buffer that contains the key pair.</returns>
		public IBuffer Export( CryptographicPrivateKeyBlobType BlobType )
		{
			throw new NotImplementedException();
		}
 /// <summary>
 /// Gets the platform-specific enum value for the given PCL enum value.
 /// </summary>
 /// <param name="blobType">The platform independent enum value for the blob type.</param>
 /// <returns>The platform-specific enum value for the equivalent blob type.</returns>
 internal static CngKeyBlobFormat GetPlatformKeyBlobType(CryptographicPrivateKeyBlobType blobType)
 {
     switch (blobType)
     {
         case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
             return CngKeyBlobFormat.Pkcs8PrivateBlob;
         default:
             throw new NotSupportedException();
     }
 }
        /// <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 byte[] Export(CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo)
 {
     throw new NotImplementedException();
 }
 /// <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[] Export(CryptographicPrivateKeyBlobType blobType)
 {
     return this.key.Export(CngAsymmetricKeyAlgorithmProvider.GetPlatformKeyBlobType(blobType));
 }
示例#48
0
 /// <inheritdoc />
 public abstract byte[] Export(CryptographicPrivateKeyBlobType blobType);
 /// <inheritdoc />
 public byte[] Export(CryptographicPrivateKeyBlobType blobType = CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo)
 {
     throw new NotSupportedException();
 }
 /// <summary>
 /// Gets the platform-specific enum value for the given PCL enum value.
 /// </summary>
 /// <param name="blobType">The platform independent enum value for the blob type.</param>
 /// <returns>The platform-specific enum value for the equivalent blob type.</returns>
 internal static Platform.CryptographicPrivateKeyBlobType GetPlatformKeyBlobType(CryptographicPrivateKeyBlobType blobType)
 {
     switch (blobType)
     {
         case CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo:
             return Platform.CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo;
         case CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey:
             return Platform.CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey;
         case CryptographicPrivateKeyBlobType.BCryptPrivateKey:
             return Platform.CryptographicPrivateKeyBlobType.BCryptPrivateKey;
         case CryptographicPrivateKeyBlobType.Capi1PrivateKey:
             return Platform.CryptographicPrivateKeyBlobType.Capi1PrivateKey;
         default:
             throw new NotSupportedException();
     }
 }