Example #1
0
        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());
		}
Example #2
0
        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);
            }
        }
Example #4
0
        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(),
 };
Example #6
0
        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());
        }
Example #7
0
        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);
        }
            //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;
            }
Example #10
0
        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());
        }
Example #11
0
 public void TestSaltStream()
 {
     Salt s = new Salt();
     Assert.AreEqual(s.ToArray(), IOStream.ReadAllBytes(s.ToStream()));
 }
Example #12
0
        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;
            }
Example #15
0
		/// <summary>
		/// Constructs the Rfc2898DeriveBytes implementation.
		/// </summary>
		public PBKDF2(byte[] password, Salt salt, int iterations)
			: base(password, salt.ToArray(), iterations)
		{ }
Example #16
0
        /// <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);
        }