示例#1
0
        /// <summary>
        /// Signs and encrypts the specified data.
        /// </summary>
        /// <param name="data">The data to encrypt.</param>
        /// <param name="privateKey">The Private key to sign the data.</param>
        /// <param name="recipients">The list of Public key recipients to encrypt the data.</param>
        /// <returns>Signed and encrypted data bytes.</returns>
        /// <exception cref="Virgil.Crypto.VirgilCryptoException"></exception>
        /// <example>
        ///   <code>
        ///     var crypto = new VirgilCrypto();
        ///     var alice = crypto.GenerateKeys();
        ///     var bob = crypto.GenerateKeys();
        ///     var originalData = Encoding.UTF8.GetBytes("Hello Bob, How are you?");
        ///     // The data to be signed with Alice's Private key and then encrypted for Bob.
        ///     var cipherData = crypto.SignThenEncrypt(originalData, alice.PrivateKey, bob.PublicKey);
        ///   </code>
        /// </example>
        public byte[] SignThenEncrypt(byte[] data, IPrivateKey privateKey, params IPublicKey[] recipients)
        {
            try
            {
                using (VirgilSigner signer = new VirgilSigner(VirgilHash.Algorithm.SHA512))
                    using (VirgilCipher cipher = new VirgilCipher())
                    {
                        byte[] signature = signer.Sign(data, VirgilCryptoExtentions.Get(privateKey).RawKey);

                        VirgilCustomParams customData = cipher.CustomParams();
                        customData.SetData(this.CustomParamKeySignature, signature);

                        IPublicKey publicKey = this.ExtractPublicKey(privateKey);

                        customData.SetData(this.CustomParamKeySignerId, VirgilCryptoExtentions.Get(publicKey).Id);

                        foreach (IPublicKey recipientPublicKey in recipients)
                        {
                            cipher.AddKeyRecipient(VirgilCryptoExtentions.Get(recipientPublicKey).Id,
                                                   VirgilCryptoExtentions.Get(recipientPublicKey).RawKey);
                        }

                        return(cipher.Encrypt(data, true));
                    }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#2
0
        /// <summary>
        /// Generates asymmetric key pair that is comprised of both public and private keys by specified type.
        /// </summary>
        /// <param name="keyPairType">type of the generated keys.
        ///   The possible values can be found in <see cref="KeyPairType"/>.</param>
        /// <param name="keyMaterial">the only data to be used for key generation,
        /// length must be more than 31.</param>
        /// <returns>Generated key pair with the specified type.</returns>
        /// <example>
        /// Generated key pair with type EC_SECP256R1.
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var keyPair = crypto.GenerateKeys(KeyPairType.EC_SECP256R1);
        ///     </code>
        /// </example>
        public KeyPair GenerateKeys(KeyPairType keyPairType, byte[] keyMaterial = null)
        {
            try
            {
                VirgilKeyPair keyPair;
                if (keyMaterial == null || keyMaterial.Length == 0)
                {
                    keyPair = VirgilKeyPair.Generate(VirgilCryptoExtentions.ToVirgilKeyPairType(keyPairType));
                }
                else
                {
                    keyPair = VirgilKeyPair.GenerateFromKeyMaterial(
                        VirgilCryptoExtentions.ToVirgilKeyPairType(keyPairType),
                        keyMaterial);
                }

                byte[]     keyPairId  = this.ComputePublicKeyHash(keyPair.PublicKey());
                PrivateKey privateKey = new PrivateKey();
                privateKey.Id     = keyPairId;
                privateKey.RawKey = VirgilKeyPair.PrivateKeyToDER(keyPair.PrivateKey());

                PublicKey publicKey = new PublicKey();
                publicKey.Id     = keyPairId;
                publicKey.RawKey = VirgilKeyPair.PublicKeyToDER(keyPair.PublicKey());

                return(new KeyPair(publicKey, privateKey));
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#3
0
        /// <summary>
        /// Decrypts and verifies the specified data.
        /// </summary>
        /// <param name="cipherData">The cipher data.</param>
        /// <param name="privateKey">The Private key to decrypt.</param>
        /// <param name="publicKeys"> The list of trusted public keys for verification,
        /// which can contain signer's public key.</param>
        /// <returns>The decrypted and verified data</returns>
        /// <exception cref="VirgilCryptoException"></exception>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var decryptedData = crypto.DecryptThenVerify(cipherData, bob.PrivateKey, alice.PublicKey);
        ///     </code>
        /// </example>
        /// <remarks>How to get cipherData as well as Alice's and Bob's key pairs
        /// <see cref="SignThenEncrypt(byte[], IPrivateKey, IPublicKey[])"/>.</remarks>
        public byte[] DecryptThenVerify(byte[] cipherData, IPrivateKey privateKey, params IPublicKey[] publicKeys)
        {
            try
            {
                using (VirgilSigner signer = new VirgilSigner(VirgilHash.Algorithm.SHA512))
                    using (VirgilCipher cipher = new VirgilCipher())
                    {
                        byte[] decryptedData =
                            cipher.DecryptWithKey(cipherData, VirgilCryptoExtentions.Get(privateKey).Id,
                                                  VirgilCryptoExtentions.Get(privateKey).RawKey);
                        byte[] signature = cipher.CustomParams().GetData(this.CustomParamKeySignature);

                        IPublicKey signerPublicKey = (publicKeys.Length > 0) ? publicKeys[0] : null;
                        if (publicKeys.Length > 1)
                        {
                            byte[] signerId = cipher.CustomParams().GetData(this.CustomParamKeySignerId);
                            signerPublicKey = FindPublicKeyBySignerId(publicKeys, signerId);
                        }

                        bool isValid = signer.Verify(decryptedData, signature, VirgilCryptoExtentions.Get(signerPublicKey).RawKey);
                        if (!isValid)
                        {
                            throw new VirgilCryptoException("Signature is not valid.");
                        }

                        return(decryptedData);
                    }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#4
0
        /// <summary>
        /// Signs the specified data using the specified Private key.
        /// </summary>
        /// <param name="data">raw data bytes for signing.</param>
        /// <param name="privateKey">private key for signing.</param>
        /// <returns>Signature data.</returns>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var keyPair = crypto.GenerateKeys();
        ///         var data = Encoding.UTF8.GetBytes("Hello Bob!");
        ///         var signature = crypto.GenerateSignature(data, keyPair.PrivateKey);
        ///     </code>
        /// </example>
        /// <remarks>How to verify signature <see cref="VerifySignature(byte[], byte[], IPublicKey)"/>.</remarks>
        public byte[] GenerateSignature(byte[] data, IPrivateKey privateKey)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (privateKey == null)
            {
                throw new ArgumentNullException("privateKey");
            }

            try
            {
                using (VirgilSigner signer = new VirgilSigner(VirgilHash.Algorithm.SHA512))
                {
                    byte[] signature = signer.Sign(data, VirgilCryptoExtentions.Get(privateKey).RawKey);
                    return(signature);
                }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#5
0
        /// <summary>
        /// Verifies the specified signature using original data and signer's Public key.
        /// </summary>
        /// <param name="data"> original data bytes for verification.</param>
        /// <param name="signature">signature bytes for verification.</param>
        /// <param name="signerKey"> signer public key for verification.</param>
        /// <returns>True if signature is valid, False otherwise.</returns>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var publicKey = crypto.ImportPublicKey(exportedPublicKey);
        ///         var data = Encoding.UTF8.GetBytes("Hello Bob!");
        ///         var isSignatureVerified = crypto.VerifySignature(signature, data, publicKey);
        ///     </code>
        /// </example>
        /// <remarks>How to generate signature <see cref="GenerateSignature(byte[], IPrivateKey)"/>.</remarks>
        /// <remarks>How to get exportedPublicKey <see cref="ExportPublicKey(IPublicKey)"/>.</remarks>
        public bool VerifySignature(byte[] signature, byte[] data, IPublicKey signerKey)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }

            try
            {
                using (VirgilSigner virgilSigner = new VirgilSigner(VirgilHash.Algorithm.SHA512))
                {
                    bool isValid = virgilSigner.Verify(data, signature, VirgilCryptoExtentions.Get(signerKey).RawKey);
                    return(isValid);
                }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#6
0
 private IPublicKey FindPublicKeyBySignerId(IPublicKey[] publicKeys, byte[] signerId)
 {
     foreach (IPublicKey publicKey in publicKeys)
     {
         if (ByteSequencesEqual(VirgilCryptoExtentions.Get(publicKey).Id, signerId))
         {
             return(publicKey);
         }
     }
     return(null);
 }
示例#7
0
 /// <summary>
 /// Exports the Public key into material representation.
 /// </summary>
 /// <param name="publicKey">public key for export.</param>
 /// <returns>Key material representation bytes.</returns>
 /// <example>
 ///     <code>
 ///         var crypto = new VirgilCrypto();
 ///         var keyPair = crypto.GenerateKeys();
 ///         var exportedPublicKey = crypto.ExportPublicKey(keyPair.PublicKey);
 ///     </code>
 /// </example>
 /// <remarks>How to import public key <see cref="ImportPublicKey(byte[])"/>.</remarks>
 /// <remarks>How to get generate keys <see cref="GenerateKeys()"/>.</remarks>
 public byte[] ExportPublicKey(IPublicKey publicKey)
 {
     try
     {
         return(VirgilKeyPair.PublicKeyToDER(VirgilCryptoExtentions.Get(publicKey).RawKey));
     }
     catch (Exception ex)
     {
         throw new VirgilCryptoException(ex.Message);
     }
 }
示例#8
0
 /// <summary>
 /// Signs the specified stream using the specified Private key.
 /// </summary>
 /// <param name="inputStream">readable stream containing input data.</param>
 /// <param name="privateKey">private key for signing.</param>
 /// <returns>Signature data.</returns>
 /// <example>
 ///     <code>
 ///         var crypto = new VirgilCrypto();
 ///         var keyPair = crypto.GenerateKeys();
 ///         using (var inputStream = new FileStream("[YOUR_FILE_PATH_HERE]", FileMode.Open, FileAccess.Read))
 ///         {
 ///             signature = crypto.GenerateSignature(inputStream, keyPair.PrivateKey);
 ///         }
 ///     </code>
 /// </example>
 /// <remarks>How to verify signature <see cref="VerifySignature(byte[], Stream, IPublicKey)"/>.</remarks>
 public byte[] GenerateSignature(Stream inputStream, IPrivateKey privateKey)
 {
     try
     {
         using (VirgilStreamSigner signer = new VirgilStreamSigner(VirgilHash.Algorithm.SHA512))
             using (VirgilStreamDataSource source = new VirgilStreamDataSource(inputStream))
             {
                 byte[] signature = signer.Sign(source, VirgilCryptoExtentions.Get(privateKey).RawKey);
                 return(signature);
             }
     }
     catch (Exception ex)
     {
         throw new VirgilCryptoException(ex.Message);
     }
 }
示例#9
0
 /// <summary>
 /// Decrypts the specified stream <see cref="cipherStream"/> using the specified Private key
 /// and writes to specified output stream <see cref="outputStream"/>
 /// <param name="cipherStream">readable stream containing encrypted data.</param>
 /// <param name="outputStream">writable stream for output.</param>
 /// <param name="privateKey">private key for decryption.</param>
 /// </summary>
 /// <example>
 ///     <code>
 ///         var crypto = new VirgilCrypto();
 ///         var alicePrivateKey = crypto.ImportPrivateKey(exportedPrivateKey);
 ///         using (var encryptedStream = new FileStream("[YOUR_CIPHER_FILE_PATH_HERE]",
 ///                 FileMode.Open, FileAccess.Read))
 ///         {
 ///             using (var decryptedStream = new FileStream("[YOUR_DECRYPTED_FILE_PATH_HERE]",
 ///                     FileMode.Create, FileAccess.Write))
 ///             {
 ///                 crypto.Decrypt(encryptedStream, decryptedStream, alicePrivateKey);
 ///             }
 ///          }
 ///     </code>
 /// </example>
 /// <remarks>How to get encryptedStream <see cref="Encrypt(Stream, Stream, IPublicKey[])"/></remarks>
 /// <remarks>How to get exportedPrivateKey <see cref="ExportPrivateKey(IPrivateKey, string)"/></remarks>
 public void Decrypt(Stream cipherStream, Stream outputStream, IPrivateKey privateKey)
 {
     try
     {
         using (VirgilChunkCipher cipher = new VirgilChunkCipher())
             using (VirgilStreamDataSource source = new VirgilStreamDataSource(cipherStream))
                 using (VirgilStreamDataSink sink = new VirgilStreamDataSink(outputStream))
                 {
                     cipher.DecryptWithKey(source, sink, VirgilCryptoExtentions.Get(privateKey).Id,
                                           VirgilCryptoExtentions.Get(privateKey).RawKey);
                 }
     }
     catch (Exception ex)
     {
         throw new VirgilCryptoException(ex.Message);
     }
 }
示例#10
0
 /// <summary>
 /// Decrypts the specified data using the specified Private key.
 /// </summary>
 /// <param name="cipherData">encrypted data bytes for decryption.</param>
 /// <param name="privateKey">private key for decryption.</param>
 /// <returns>Decrypted data bytes.</returns>
 /// <example>
 ///     <code>
 ///         var crypto = new VirgilCrypto();
 ///         var keyPair = crypto.GenerateKeys();
 ///         var plainData = crypto.Decrypt(encryptedData, keyPair.PrivateKey);
 ///     </code>
 /// </example>
 /// <remarks>How to get encryptedData <see cref="Encrypt(byte[], IPublicKey[])"/>.</remarks>
 public byte[] Decrypt(byte[] cipherData, IPrivateKey privateKey)
 {
     try
     {
         using (VirgilCipher cipher = new VirgilCipher())
         {
             byte[] data = cipher.DecryptWithKey(cipherData,
                                                 VirgilCryptoExtentions.Get(privateKey).Id,
                                                 VirgilCryptoExtentions.Get(privateKey).RawKey);
             return(data);
         }
     }
     catch (Exception ex)
     {
         throw new VirgilCryptoException(ex.Message);
     }
 }
示例#11
0
        /// <summary>
        /// Extracts the Public key from the specified <see cref="IPrivateKey"/>
        /// </summary>
        /// <param name="privateKey"> The private key.</param>
        /// <returns>The instance of <see cref="IPublicKey"/></returns>
        public IPublicKey ExtractPublicKey(IPrivateKey privateKey)
        {
            try
            {
                byte[] publicKeyData = VirgilKeyPair.ExtractPublicKey(
                    VirgilCryptoExtentions.Get(privateKey).RawKey, new byte[] { });

                PublicKey publicKey = new PublicKey();
                publicKey.Id     = VirgilCryptoExtentions.Get(privateKey).Id;
                publicKey.RawKey = VirgilKeyPair.PublicKeyToDER(publicKeyData);

                return(publicKey);
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#12
0
        /// <summary>
        /// Verifies the specified signature using original stream and signer's Public key.
        /// </summary>
        /// <param name="inputStream">readable stream containing input data.</param>
        /// <param name="publicKey">signer public key for verification.</param>
        /// <param name="signature">signature bytes for verification.</param>
        /// <returns>True if signature is valid, False otherwise.</returns>
        /// <example>
        /// <code>
        ///    var publicKey = crypto.ImportPublicKey(exportedPublicKey);
        ///    using (var inputStream = new FileStream("[YOUR_FILE_PATH_HERE]", FileMode.Open, FileAccess.Read))
        ///    {
        ///       crypto.Verify(inputStream, signature, publicKey);
        ///    }
        /// </code>
        /// </example>
        /// <remarks>How to get exportedPublicKey <see cref="ExportPublicKey(IPublicKey)"/>.</remarks>
        /// <remarks>How to genrate signature <see cref="GenerateSignature(Stream, IPrivateKey)"/>.</remarks>
        public bool VerifySignature(byte[] signature, Stream inputStream, IPublicKey publicKey)
        {
            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }

            try
            {
                using (VirgilStreamSigner streamSigner = new VirgilStreamSigner(VirgilHash.Algorithm.SHA512))
                {
                    VirgilStreamDataSource source = new VirgilStreamDataSource(inputStream);
                    bool isValid = streamSigner.Verify(source, signature, VirgilCryptoExtentions.Get(publicKey).RawKey);
                    return(isValid);
                }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#13
0
        /// <summary>
        /// Encrypts the specified data using the specified recipients Public keys.
        /// </summary>
        /// <param name="data">raw data bytes for encryption.</param>
        /// <param name="recipients"> list of recipients' public keys.</param>
        /// <returns>Encrypted bytes.</returns>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var keyPair = crypto.GenerateKeys();
        ///         var data = Encoding.UTF8.GetBytes("Encrypt me!");
        ///         var encryptedData = crypto.Encrypt(data, keyPair.PublicKey);
        ///     </code>
        /// </example>
        /// <remarks>How to decrypt data <see cref="Decrypt(byte[], Virgil.CryptoAPI.IPrivateKey)"/>.</remarks>
        public byte[] Encrypt(byte[] data, params IPublicKey[] recipients)
        {
            try
            {
                using (VirgilCipher cipher = new VirgilCipher())
                {
                    foreach (IPublicKey publicKey in recipients)
                    {
                        cipher.AddKeyRecipient(VirgilCryptoExtentions.Get(publicKey).Id,
                                               VirgilCryptoExtentions.Get(publicKey).RawKey);
                    }

                    byte[] encryptedData = cipher.Encrypt(data, true);
                    return(encryptedData);
                }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#14
0
        /// <summary>
        /// Encrypts the specified stream <see cref="inputStream"/> using the specified recipients Public keys
        /// and writes to specified output stream <see cref="cipherStream"/>.
        /// </summary>
        /// <param name="inputStream">readable stream containing input bytes.</param>
        /// <param name="cipherStream">writable stream for output.</param>
        /// <param name="recipients"> list of recipients' public keys.</param>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var aliceKeyPair = crypto.GenerateKeys();
        ///         var bobKeyPair = crypto.GenerateKeys();
        ///         using (var inputStream = new FileStream("[YOUR_FILE_PATH_HERE]",
        ///         FileMode.Open, FileAccess.Read))
        ///         {
        ///             using (var cipherStream = new FileStream("[YOUR_CIPHER_FILE_PATH_HERE]",
        ///             FileMode.Create, FileAccess.Write))
        ///             {
        ///                crypto.Encrypt(inputStream, cipherStream, aliceKeyPair.PublicKey, bobKeyPair.PublicKey);
        ///             }
        ///          }
        ///     </code>
        /// </example>
        public void Encrypt(Stream inputStream, Stream cipherStream, params IPublicKey[] recipients)
        {
            try
            {
                using (VirgilChunkCipher cipher = new VirgilChunkCipher())
                    using (VirgilStreamDataSource source = new VirgilStreamDataSource(inputStream))
                        using (VirgilStreamDataSink sink = new VirgilStreamDataSink(cipherStream))
                        {
                            foreach (IPublicKey publicKey in recipients)
                            {
                                cipher.AddKeyRecipient(VirgilCryptoExtentions.Get(publicKey).Id,
                                                       VirgilCryptoExtentions.Get(publicKey).RawKey);
                            }

                            cipher.Encrypt(source, sink);
                        }
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }
示例#15
0
        /// <summary>
        /// Exports the Private key into material representation.
        /// </summary>
        /// <param name="privateKey">private key for export.</param>
        /// <param name="password">password that is used for encryption of private key raw bytes.</param>
        /// <returns>Private key material representation bytes.</returns>
        /// <example>
        ///     <code>
        ///         var crypto = new VirgilCrypto();
        ///         var keyPair = crypto.GenerateKeys();
        ///         var crypto = new VirgilCrypto();
        ///         var exportedPrivateKey = crypto.ExportPrivateKey(keyPair.PrivateKey, "my_password");
        ///     </code>
        /// </example>
        /// <remarks>How to import private key <see cref="ImportPrivateKey(byte[], string)"/>.</remarks>
        /// <remarks>How to get generate keys <see cref="VirgilCrypto.GenerateKeys()"/>.</remarks>
        public byte[] ExportPrivateKey(IPrivateKey privateKey, string password)
        {
            if (privateKey == null)
            {
                throw new ArgumentNullException("privateKey");
            }
            try
            {
                if (string.IsNullOrEmpty(password))
                {
                    return(VirgilKeyPair.PrivateKeyToDER(VirgilCryptoExtentions.Get(privateKey).RawKey));
                }

                byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
                byte[] encryptedKey  = VirgilKeyPair.EncryptPrivateKey(VirgilCryptoExtentions.Get(privateKey).RawKey,
                                                                       passwordBytes);

                return(VirgilKeyPair.PrivateKeyToDER(encryptedKey, passwordBytes));
            }
            catch (Exception ex)
            {
                throw new VirgilCryptoException(ex.Message);
            }
        }