/// <summary> /// Converts the value of the current <see cref="SecureSymmetricKey" /> to its equivalent binary representation. /// </summary> /// <returns> /// A binary representation of the current <see cref="SecureSymmetricKey" />. /// </returns> public SecureBuffer ToBuffer() { var resultBuffer = new SecureBuffer(SerializedLength); try { using (var controlToken = StateControl.Enter()) { using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true)) { KeySource.Access(pinnedKeySourceBuffer => { Array.Copy(pinnedKeySourceBuffer, 0, plaintextBuffer, KeySourceBufferIndex, KeySourceLengthInBytes); }); plaintextBuffer[AlgorithmBufferIndex] = (Byte)Algorithm; plaintextBuffer[DerivationModeBufferIndex] = (Byte)DerivationMode; using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider)) { using (var initializationVector = new PinnedBuffer(cipher.BlockSizeInBytes, true)) { RandomnessProvider.GetBytes(initializationVector); resultBuffer.Access(pinnedResultBuffer => { using (var ciphertext = cipher.Encrypt(plaintextBuffer, BufferEncryptionKey, initializationVector)) { Array.Copy(ciphertext, 0, pinnedResultBuffer, 0, SerializedLength); } }); } } } } return(resultBuffer); } catch { resultBuffer.Dispose(); throw new SecurityException("Key serialization failed."); } }
/// <summary> /// Creates a new instance of a <see cref="SecureSymmetricKey" /> using the specified buffer. /// </summary> /// <param name="buffer"> /// A binary representation of a <see cref="SecureSymmetricKey" />. /// </param> /// <returns> /// A new instance of a <see cref="SecureSymmetricKey" />. /// </returns> /// <exception cref="ArgumentException"> /// <paramref name="buffer" /> is invalid. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="buffer" /> is <see langword="null" />. /// </exception> public static SecureSymmetricKey FromBuffer(SecureBuffer buffer) { buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid."); try { var result = (SecureSymmetricKey)null; buffer.Access(pinnedCiphertext => { using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true)) { using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider)) { using (var plaintext = cipher.Decrypt(pinnedCiphertext, BufferEncryptionKey)) { Array.Copy(plaintext, 0, plaintextBuffer, 0, SerializedPlaintextLength); } } using (var keySource = new PinnedBuffer(KeySourceLengthInBytes, true)) { Array.Copy(plaintextBuffer, KeySourceBufferIndex, keySource, 0, KeySourceLengthInBytes); var algorithm = (SymmetricAlgorithmSpecification)plaintextBuffer[AlgorithmBufferIndex]; var derivationMode = (SecureSymmetricKeyDerivationMode)plaintextBuffer[DerivationModeBufferIndex]; result = new SecureSymmetricKey(algorithm, derivationMode, keySource); } } }); return(result); } catch { throw new ArgumentException("The specified buffer is invalid.", nameof(buffer)); } }