public byte[] UnwrapMasterKey(AesKey keyEncryptingKey, byte fileVersionMajor) { byte[] wrappedKeyData = GetKeyData(); KeyWrapSalt salt = Salt; if (fileVersionMajor <= 1) { // Due to a bug in 1.1 and earlier we only used a truncated part of the key and salt :-( // Compensate for this here. Users should be warned if FileVersionMajor <= 1 . byte[] badKey = new byte[keyEncryptingKey.Length]; Array.Copy(keyEncryptingKey.GetBytes(), 0, badKey, 0, 4); keyEncryptingKey = new AesKey(badKey); byte[] badSalt = new byte[salt.Length]; Array.Copy(salt.GetBytes(), 0, badSalt, 0, 4); salt = new KeyWrapSalt(badSalt); } byte[] unwrappedKeyData; using (KeyWrap keyWrap = new KeyWrap(keyEncryptingKey, salt, Iterations, KeyWrapMode.AxCrypt)) { unwrappedKeyData = keyWrap.Unwrap(wrappedKeyData); } return(unwrappedKeyData); }
public static void TestMethodsEtc() { KeyWrapSalt salt = null; Assert.DoesNotThrow(() => { salt = new KeyWrapSalt(16); Assert.That(salt.Length, Is.EqualTo(16), "The length should be what was asked for."); Assert.That(salt.GetBytes(), Is.Not.EquivalentTo(new byte[16]), "A random salt is not likely to be all zeros."); salt = new KeyWrapSalt(24); Assert.That(salt.Length, Is.EqualTo(24), "The length should be what was asked for."); Assert.That(salt.GetBytes(), Is.Not.EquivalentTo(new byte[24]), "A random salt is not likely to be all zeros."); salt = new KeyWrapSalt(32); Assert.That(salt.Length, Is.EqualTo(32), "The length should be what was asked for."); Assert.That(salt.GetBytes(), Is.Not.EquivalentTo(new byte[32]), "A random salt is not likely to be all zeros."); salt = new KeyWrapSalt(new byte[16]); Assert.That(salt.GetBytes(), Is.EquivalentTo(new byte[16]), "A salt with all zeros was requested."); salt = new KeyWrapSalt(new byte[24]); Assert.That(salt.GetBytes(), Is.EquivalentTo(new byte[24]), "A salt with all zeros was requested."); salt = new KeyWrapSalt(new byte[32]); Assert.That(salt.GetBytes(), Is.EquivalentTo(new byte[32]), "A salt with all zeros was requested."); salt = new KeyWrapSalt(new byte[0]); Assert.That(salt.Length, Is.EqualTo(0), "As a special case, zero length salt is supported - equivalent to no salt."); } ); Assert.Throws <ArgumentNullException>(() => { salt = new KeyWrapSalt(null); }); Assert.Throws <InternalErrorException>(() => { salt = new KeyWrapSalt(0); }); Assert.Throws <InternalErrorException>(() => { salt = new KeyWrapSalt(-16); }); Assert.Throws <InternalErrorException>(() => { salt = new KeyWrapSalt(48); }); Assert.Throws <InternalErrorException>(() => { salt = new KeyWrapSalt(new byte[12]); }); }
public static void TestAesKeyThumbprintMethods() { AesKey key1 = new AesKey(new byte[] { 5, 6, 7, 8, 2, 4, 55, 77, 34, 65, 89, 12, 45, 87, 54, 255 }); AesKey key2 = new AesKey(new byte[] { 5, 6, 7, 8, 2, 4, 55, 77, 34, 65, 89, 12, 45, 87, 54, 255 }); KeyWrapSalt salt1 = new KeyWrapSalt(16); KeyWrapSalt salt2 = new KeyWrapSalt(salt1.GetBytes()); AesKeyThumbprint thumbprint1 = new AesKeyThumbprint(key1, salt1, 10); AesKeyThumbprint thumbprint2 = new AesKeyThumbprint(key2, salt2, 10); Assert.That(thumbprint1 == thumbprint2, "Two thumb prints made from the same key and salt bytes, although different AesKey instances should be equivalent."); AesKeyThumbprint thumbprint3 = new AesKeyThumbprint(new AesKey(), new KeyWrapSalt(AesKey.DefaultKeyLength), 10); Assert.That(thumbprint2 != thumbprint3, "Two very different keys and salts should not be equivalent."); }
protected void Set(byte[] wrapped, KeyWrapSalt salt, long iterations) { if (wrapped == null) { throw new ArgumentNullException("wrapped"); } if (wrapped.Length != 16 + 8) { throw new ArgumentException("wrapped must be 128 bits + 8 bytes."); } if (salt == null) { throw new ArgumentNullException("salt"); } if (salt.Length != 16) { throw new ArgumentException("salt must have same length as the wrapped key, i.e. 128 bits."); } Array.Copy(wrapped, 0, GetDataBlockBytesReference(), 0, wrapped.Length); Array.Copy(salt.GetBytes(), 0, GetDataBlockBytesReference(), 16 + 8, salt.Length); byte[] iterationsBytes = iterations.GetLittleEndianBytes(); Array.Copy(iterationsBytes, 0, GetDataBlockBytesReference(), 16 + 8 + 16, sizeof(uint)); }