public void TestSaltCopy() { Salt s = new Salt(); byte[] bytes = new byte[s.Length]; s.CopyTo(bytes, 0); Assert.AreEqual(s.ToArray(), bytes); Assert.AreEqual(s.GetHashCode(), Salt.FromBytes(bytes).GetHashCode()); Salt strcpy = Salt.FromString(s.ToString()); Assert.AreEqual(s.ToArray(), strcpy.ToArray()); Assert.AreEqual(s.ToString(), strcpy.ToString()); Assert.AreEqual(s.GetHashCode(), strcpy.GetHashCode()); }
public void TestSalt() { using (IPasswordDerivedBytes pd = DerivedBytes(TEST_PASSWORD)) { Assert.AreEqual(DefaultSalt.ToArray(), pd.Salt); byte[] bytes = pd.GetBytes(4); pd.Salt = new Salt().ToArray(); Assert.AreNotEqual(bytes, pd.GetBytes(bytes.Length)); Assert.AreNotEqual(DefaultSalt.ToArray(), pd.Salt); pd.Salt = DefaultSalt.ToArray(); Assert.AreEqual(bytes, pd.GetBytes(bytes.Length)); Assert.AreEqual(DefaultSalt.ToArray(), pd.Salt); } }
public void TestCreateSalt() { Salt s = new Salt(); Assert.AreEqual(32, s.Length); Assert.AreNotEqual(new byte[32], s.ToArray()); Salt s8 = new Salt(Salt.Size.b64); Assert.AreEqual(8, s8.Length); Assert.AreEqual(Salt.Size.b64, s8.BitSize); Salt s16 = new Salt(Salt.Size.b128); Assert.AreEqual(16, s16.Length); Assert.AreEqual(Salt.Size.b128, s16.BitSize); Salt s32 = new Salt(Salt.Size.b256); Assert.AreEqual(32, s32.Length); Assert.AreEqual(Salt.Size.b256, s32.BitSize); Salt s64 = new Salt(Salt.Size.b512); Assert.AreEqual(64, s64.Length); Assert.AreEqual(Salt.Size.b512, s64.BitSize); }
/// <summary> /// Makes a deep clone of current instance. /// </summary> /// <returns>A deep clone of the current instance.</returns> public IBlake2BConfig Clone() => new Blake2BConfig() { HashSizeInBits = HashSizeInBits, Key = Key?.ToArray(), Salt = Salt?.ToArray(), Personalization = Personalization?.ToArray(), };
public void TestEquality() { Salt s = new Salt(); Salt scopy = Salt.FromBytes(s.ToArray()); Assert.AreEqual(s, scopy); Assert.IsTrue(s.Equals(scopy)); Assert.IsTrue(s.Equals((object)scopy)); Assert.IsTrue(s == scopy); Assert.IsFalse(s != scopy); Assert.AreEqual(s.GetHashCode(), scopy.GetHashCode()); scopy = new Salt(); Assert.AreNotEqual(s, scopy); Assert.IsFalse(s.Equals(scopy)); Assert.IsFalse(s.Equals((object)scopy)); Assert.IsFalse(s == scopy); Assert.IsTrue(s != scopy); Assert.AreNotEqual(s.GetHashCode(), scopy.GetHashCode()); }
//private bool _verified; /* this is a debugging aid used to ensure all messages are signed or verified */ public Message(TransferState state, Guid transferId, RSAPublicKey key, Converter<Guid, Salt> sessionSecret) { _version = VersionHeader; _state = state; _transferId = transferId; _salt = new Salt(Salt.Size.b256); _protected = new MemoryStream(); _payload = new NonClosingStream(_protected); _hash = new HashStream(new SHA256Managed()); WriteHeader(_hash); Salt secret; if (!UsesSessionKey) { // Outer encryption is straight PKI based on the remote public key _payload = key.Encrypt(_payload); _hash.ChangeStream(_payload); // Preceed the message with a new, AES key secret = new Salt(Salt.Size.b256); _hash.Write(secret.ToArray(), 0, 32); } else { secret = sessionSecret(_transferId); Check.IsEqual(32, Check.NotNull(secret).Length); } AESCryptoKey sessionKey = new AESCryptoKey( // Prefix the key with the message's salt and compute a SHA256 hash to be used as the key Hash.SHA256(_salt.GetData(secret.ToArray()).ToStream()).ToArray(), // Compute an IV for this aes key and salt combination IV(secret, _salt) ); _payload = sessionKey.Encrypt(_payload); _hash.ChangeStream(_payload); }
private byte[] IV(Salt secret, Salt salt) { // Long story, this has been a little difficult to finally settle upon an algorithm. // We know we don't want to the same value each time, and we prefer not to use only // the public salt. My biggest concern is not generating a IV value that interacts // with AES in a way that might divulge information unintentionally. Since we are // using the same values (salt+secret) to derive the IV this is a very real risk. // To mitigate this risk the primary interaction of secret in the derivation of this // value is compressed into a CRC of both the salt and secret. This value is then // masked with computations of salt to produce the 16 IV bytes needed. byte[] sbytes = salt.ToArray(); byte[] result = new byte[16]; // compute a mask from CRC32(salt + secret) int mask = new Crc32(_salt.GetData(secret.ToArray()).ToArray()).Value; // xor part of the mask with the sum of two salt bytes for (int i = 0; i < 16; i++) result[i] = (byte)((mask >> i) ^ (sbytes[i] + sbytes[i + 16])); return result; }
public void TestSaltStream() { Salt s = new Salt(); Assert.AreEqual(s.ToArray(), IOStream.ReadAllBytes(s.ToStream())); }
private Salt BeginUpload(Guid transferId, string location, long length, out int maxMessageLength) { byte[] serverKeyBits; byte[] nonce = GetNonce(transferId, location, out serverKeyBits); Hash hnonce = Hash.SHA256(nonce); //STEP 2: Create and send session key Salt clientKeyBits = new Salt(Salt.Size.b256); Salt sessionSecret = SessionSecret(clientKeyBits, serverKeyBits); using (Message req = new Message(TransferState.UploadRequest, transferId, _publicKey, NoSession)) { req.Write(hnonce.ToArray()); req.Write(length); req.Write(location); req.Write(clientKeyBits.ToArray()); Stream response = SendPayload(req, location, req.ToStream(_privateKey)); using (Message rsp = new Message(response, _privateKey, s=>sessionSecret)) { Check.Assert<InvalidOperationException>(rsp.State == TransferState.UploadResponse); maxMessageLength = Check.InRange(rsp.ReadInt32(), 0, int.MaxValue); rsp.VerifySignature(_publicKey); } } return sessionSecret; }
private bool Download(string location, StreamCache output) { int maxMessageLength; long fileLength, bytesReceived = 0; Guid transferId = Guid.NewGuid(); byte[] serverKeyBits; byte[] nonce = GetNonce(transferId, location, out serverKeyBits); Hash hnonce = Hash.SHA256(nonce); //STEP 2: Create and send session key Salt clientKeyBits = new Salt(Salt.Size.b256); Salt sessionKey = SessionSecret(clientKeyBits, serverKeyBits); using (Message req = new Message(TransferState.DownloadRequest, transferId, _publicKey, NoSession)) { req.Write(hnonce.ToArray()); req.Write(location); req.Write(clientKeyBits.ToArray()); Stream response = SendPayload(req, location, req.ToStream(_privateKey)); using (Message rsp = new Message(response, _privateKey, s=>sessionKey)) { Check.Assert<InvalidOperationException>(rsp.State == TransferState.DownloadResponse); maxMessageLength = Check.InRange(rsp.ReadInt32(), 0, int.MaxValue); fileLength = Check.InRange(rsp.ReadInt64(), 0, 0x00FFFFFFFFFFFFFFL); byte[] bytes = rsp.ReadBytes(100 * 1000 * 1024); rsp.VerifySignature(_publicKey); using(Stream io = output.Open(FileAccess.Write)) { io.SetLength(fileLength); if (bytes.Length > 0) { io.Seek(0, SeekOrigin.Begin); io.Write(bytes, 0, bytes.Length); bytesReceived += bytes.Length; } } } } //STEP 3...n: Continue downloading other chunks of the file if (bytesReceived < fileLength) { bool[] failed = new bool[1]; using (WorkQueue queue = new WorkQueue(LimitThreads)) { queue.OnError += (o, e) => { failed[0] = true; }; while (bytesReceived < fileLength && !failed[0] && !_abort.WaitOne(0, false)) { int len = (int) Math.Min(fileLength - bytesReceived, maxMessageLength); BytesToRead task = new BytesToRead( this, LimitThreads, transferId, sessionKey, location, output, bytesReceived, len); queue.Enqueue(task.Send); OnProgressChanged(location, bytesReceived, fileLength); bytesReceived += len; } queue.Complete(true, failed[0] ? 5000 : 7200000); } if (_abort.WaitOne(0, false)) return false; Check.Assert<InvalidDataException>(failed[0] == false); // STEP 4: Complete the transfer using (Message req = new Message(TransferState.DownloadCompleteRequest, transferId, _publicKey, s => sessionKey)) { SendPayload(req, location, req.ToStream(_privateKey)).Dispose(); } } OnProgressChanged(location, fileLength, fileLength); return true; }
/// <summary> /// Constructs the Rfc2898DeriveBytes implementation. /// </summary> public PBKDF2(byte[] password, Salt salt, int iterations) : base(password, salt.ToArray(), iterations) { }
/// <summary> Returns the key generated with the current password and the provided salt </summary> public AESCryptoKey CreateKey(Salt salt, byte[] iv) { DerivedBytes.Salt = salt.ToArray(); DerivedBytes.Reset(); byte[] key = DerivedBytes.GetBytes(32); return new AESCryptoKey(key, iv); }