/// <summary> /// Encrypts the specified plain data. /// </summary> /// <param name="plainData">The plain data.</param> /// <param name="remotePublicKeyXML">The remote public key XML.</param> /// <returns> /// The encrypted data. /// </returns> /// <externalUnit/> /// <revision revisor="dev01" date="1/26/2009" version="1.0.5.7"> /// Member Created /// </revision> public byte[] Encrypt( byte[] plainData, string remotePublicKeyXML) { // Ecnrypted data placeholder byte[] encryptedData = null; //Calculate the hash and append it to the data byte[] dataPlusHash = SequoiaCryptoProvider.AppendArrays( this.CalculateHash(plainData), plainData); // Symmetrically Encrypt data and hash with random key and IV byte[] encryptedDataPlusHash = this.SymmetricallyEncryptContent(dataPlusHash); // Create an Encrypted transport Key var transKey = new TransportKey( this.SymmetricCrypto.Key, this.SymmetricCrypto.IV, this); // Add transport Key to ecnrypted data encryptedData = SequoiaCryptoProvider.AppendArrays( transKey.GenerateTransportKey(remotePublicKeyXML), encryptedDataPlusHash); return(encryptedData); }
/// <summary> /// Decrypts the specified complete encrypted data. /// </summary> /// <param name="completeEncryptedData">The complete encrypted data.</param> /// <param name="localPrivateKeyXML">The local private key XML.</param> /// <returns> /// The decrypted data. /// </returns> /// <externalUnit/> /// <revision revisor="dev01" date="1/26/2009 1:23:15 PM" version="1.0.5.7"> /// Member Created /// </revision> public byte[] Decrypt( byte[] completeEncryptedData, string localPrivateKeyXML) { byte[] decryptedData = null; byte[] hash = null; try { // Generate the Transport Key TransportKey transportKey = new TransportKey( SequoiaCryptoProvider.Subarray( completeEncryptedData, 0, this.TransportKeySize), this); // Extract encrypted data (total - transport key) byte[] encryptedData = SequoiaCryptoProvider.Subarray( completeEncryptedData, this.TransportKeySize); // Decrypt the data and Hash with decrypted symmetric key and IV byte[] decryptedDataPlusHash = this.SymmetricallyDecryptContent( encryptedData, transportKey.GetSymmetricKeyFromTransportKey( localPrivateKeyXML), transportKey.GetSymmetricIVFromTransportKey( localPrivateKeyXML)); hash = SequoiaCryptoProvider.Subarray( decryptedDataPlusHash, 0, this.Hasher.HashSize / BitsInByte); // Extarct the final data decryptedData = SequoiaCryptoProvider.Subarray( decryptedDataPlusHash, this.Hasher.HashSize / BitsInByte); } catch (Exception exc) { throw new CryptographicException("Wrong data to decrypt.", exc); } if (SequoiaCryptoProvider.CompareHashes( hash, this.CalculateHash(decryptedData)) != true) { throw new CryptographicException("Hash Mismatch."); } return(decryptedData); }
/// <summary> /// Initializes a new instance of the <see cref="TransportKey"/> class. /// </summary> /// <param name="encryptedKey">The encrypted key.</param> /// <param name="crypto">The crypto provider.</param> /// <externalUnit/> /// <revision revisor="dev01" date="1/30/2009" version="1.0.5.11"> /// Member Created /// </revision> public TransportKey( byte[] encryptedKey, SequoiaCryptoProvider crypto) { this.encryptedData = encryptedKey; this.encrypted = true; this.asymmetricCrypto = crypto.AsymmetricCrypto; this.shortKeys = crypto.ShortKeys; }
/// <summary> /// Creates a sub version of the array /// </summary> /// <returns>The piece of the array</returns> /// <param name="mainArray">First Array to merge</param> /// <param name="index">Index to start the subarray </param> /// <revision revisor="dev01" date="1/28/2009" version="1.0.5.9"> /// Method created. /// </revision> public static byte[] Subarray( byte[] mainArray, int index) { return(SequoiaCryptoProvider.Subarray( mainArray, index, mainArray.Length - index)); }
/// <summary> /// Initializes a new instance of the <see cref="TransportKey"/> class. /// </summary> /// <param name="crypto">The crypto.</param> /// <externalUnit/> /// <revision revisor="dev01" date="2/5/2009" version="1.0.6.1"> /// Member Created /// </revision> public TransportKey( SequoiaCryptoProvider crypto) { this.key = crypto.SymmetricCrypto.Key; this.asymmetricCrypto = crypto.AsymmetricCrypto; this.initializationVector = crypto.SymmetricCrypto.IV; this.encrypted = false; this.shortKeys = crypto.ShortKeys; }
/// <summary> /// Initializes a new instance of the <see cref="TransportKey"/> class. /// </summary> /// <param name="encryptionKey">The encryption key.</param> /// <param name="initializationVector"> /// The initialization vector. /// </param> /// <param name="crypto">the crypto provider.</param> /// <externalUnit/> /// <revision revisor="dev01" date="1/30/2009" version="1.0.5.11"> /// Member Created /// </revision> public TransportKey( byte[] encryptionKey, byte[] initializationVector, SequoiaCryptoProvider crypto) { this.asymmetricCrypto = crypto.AsymmetricCrypto; this.key = encryptionKey; this.initializationVector = initializationVector; this.encrypted = false; this.shortKeys = crypto.ShortKeys; }
/// <summary> /// Generates the transport key. /// </summary> /// <param name="remotePublicKeyXML">The remote public key XML.</param> /// <returns> /// The transport key. /// </returns> /// <externalUnit cref="AsymmetricAlgorithm"/> /// <revision revisor="dev01" date="1/30/2009" version="1.0.5.11"> /// Member Created /// </revision> public byte[] GenerateTransportKey(string remotePublicKeyXML) { if (encrypted == false) { this.encryptedData = SequoiaCryptoProvider.AppendArrays( this.AsymmetricallyEncryptContent( this.key, remotePublicKeyXML), this.AsymmetricallyEncryptContent( this.initializationVector, remotePublicKeyXML)); encrypted = true; } return(this.encryptedData); }
/// <summary> /// Decrypts the transport key. /// </summary> /// <param name="privateKeyXML">The private key XML.</param> /// <externalUnit/> /// <revision revisor="dev01" date="1/30/2009" version="1.0.5.11"> /// Member Created /// </revision> public void DecryptTransportKey(string privateKeyXML) { if (this.encrypted == true) { this.key = this.AsymmetricallyDecryptContent( SequoiaCryptoProvider.Subarray( this.encryptedData, 0, this.AsymmetricCrypto.KeySize / 8), privateKeyXML); this.initializationVector = this.AsymmetricallyDecryptContent( SequoiaCryptoProvider.Subarray( this.encryptedData, this.AsymmetricCrypto.KeySize / 8), privateKeyXML); this.encrypted = false; } }
/// <summary> /// Symmetrically decrypt the content. /// </summary> /// <param name="encryptedData">The encrypted data.</param> /// <param name="symmetricKey">The symmetric key.</param> /// <param name="symmetricIV">The symmetric IV.</param> /// <returns> /// The decrypted content. /// </returns> /// <externalUnit/> /// <revision revisor="dev01" date="1/26/2009 1:23:15 PM" version="1.0.5.7"> /// Member Created /// </revision> private byte[] SymmetricallyDecryptContent( byte[] encryptedData, byte[] symmetricKey, byte[] symmetricIV) { // Memory Stream to read the encrypted data byte[] decryptedBytes = null; int decryptRealSize = 0; // Cryptostream to decrypt teh memory stream using (var memoryStream = new MemoryStream(encryptedData)) { using (var cryptoStream = new CryptoStream( memoryStream, this.SymmetricCrypto.CreateDecryptor( symmetricKey, symmetricIV), CryptoStreamMode.Read)) { // Placeholder for decrypted data (size it with the // encrypted data length (maybe larger but then // will crop it) decryptedBytes = new byte[encryptedData.Length]; // Start decrypting. decryptRealSize = cryptoStream.Read( decryptedBytes, 0, encryptedData.Length); } } // REVIEW: null check on decrypted bytes before proceeding. // Need subarray, because placeholder array maybe larger than the // actual data return(SequoiaCryptoProvider.Subarray( decryptedBytes, 0, decryptRealSize)); }