Пример #1
0
        public static byte[] DecryptData(string strData, byte[] pbKey32,
			byte[] pbIV16)
        {
            if(!strData.StartsWith("s20://")) return null;

            string strEnc = strData.Substring(6);
            byte[] pb = Convert.FromBase64String(strEnc);

            byte[] pbIV8 = new byte[8];
            Array.Copy(pbIV16, 0, pbIV8, 0, 8);

            Salsa20Cipher dec = new Salsa20Cipher(pbKey32, pbIV8);
            dec.Encrypt(pb, pb.Length, true);

            return pb;
        }
        public Salsa20RandomGenerator(IBuffer key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            key = HashAlgorithmProvider
                .OpenAlgorithm(HashAlgorithmNames.Sha256)
                .HashData(key);

            var iv = new byte[]
            {
                0xE8, 0x30, 0x09, 0x4B,
                0x97, 0x20, 0x5D, 0x2A
            };

            _cipher = new Salsa20Cipher(key.ToArray(), iv);
        }
Пример #3
0
		private static int Salsa20ToPos(Salsa20Cipher c, Random r, int nPos,
			int nTargetPos)
		{
			byte[] pb = new byte[512];

			while(nPos < nTargetPos)
			{
				int x = r.Next(1, 513);
				int nGen = Math.Min(nTargetPos - nPos, x);
				c.Encrypt(pb, nGen, r.Next(0, 2) == 0);
				nPos += nGen;
			}

			return nTargetPos;
		}
Пример #4
0
		private static void TestSalsa20()
		{
			// Test values from official set 6, vector 3
			byte[] pbKey= new byte[32] {
				0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
				0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
				0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
				0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
			};
			byte[] pbIV = new byte[8] { 0x28, 0x8F, 0xF6, 0x5D,
				0xC4, 0x2B, 0x92, 0xF9 };
			byte[] pbExpected = new byte[16] {
				0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
				0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
			};

			byte[] pb = new byte[16];
			Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
			c.Encrypt(pb, pb.Length, false);
			if(!MemUtil.ArraysEqual(pb, pbExpected))
				throw new SecurityException("Salsa20-1");

#if DEBUG
			// Extended test in debug mode
			byte[] pbExpected2 = new byte[16] {
				0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
				0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
			};
			byte[] pbExpected3 = new byte[16] {
				0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
				0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
			};

			Random r = new Random();
			int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
			c.Encrypt(pb, pb.Length, false);
			if(!MemUtil.ArraysEqual(pb, pbExpected2))
				throw new SecurityException("Salsa20-2");

			nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
			Array.Clear(pb, 0, pb.Length);
			c.Encrypt(pb, pb.Length, true);
			if(!MemUtil.ArraysEqual(pb, pbExpected3))
				throw new SecurityException("Salsa20-3");

			Dictionary<string, bool> d = new Dictionary<string, bool>();
			const int nRounds = 100;
			for(int i = 0; i < nRounds; ++i)
			{
				byte[] z = new byte[32];
				c = new Salsa20Cipher(z, BitConverter.GetBytes((long)i));
				c.Encrypt(z, z.Length, true);
				d[MemUtil.ByteArrayToHexString(z)] = true;
			}
			if(d.Count != nRounds) throw new SecurityException("Salsa20-4");
#endif
		}
Пример #5
0
        /// <summary>
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="genAlgorithm">Algorithm to use.</param>
        /// <param name="pbKey">Initialization key. Must not be <c>null</c> and
        /// must contain at least 1 byte.</param>
        /// <exception cref="System.ArgumentNullException">Thrown if the
        /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentException">Thrown if the
        /// <paramref name="pbKey" /> parameter contains no bytes or the
        /// algorithm is unknown.</exception>
        public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
        {
            m_crsAlgorithm = genAlgorithm;

            Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey");

            uint uKeyLen = (uint)pbKey.Length;
            Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException();

            if(genAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                // Fill the state linearly
                m_pbState = new byte[256];
                for(uint w = 0; w < 256; ++w) m_pbState[w] = (byte)w;

                unchecked
                {
                    byte j = 0, t;
                    uint inxKey = 0;
                    for(uint w = 0; w < 256; ++w) // Key setup
                    {
                        j += (byte)(m_pbState[w] + pbKey[inxKey]);

                        t = m_pbState[0]; // Swap entries
                        m_pbState[0] = m_pbState[j];
                        m_pbState[j] = t;

                        ++inxKey;
                        if(inxKey >= uKeyLen) inxKey = 0;
                    }
                }

                GetRandomBytes(512); // Increases security, see cryptanalysis
            }
            else if(genAlgorithm == CrsAlgorithm.Salsa20)
            {
                SHA256Managed sha256 = new SHA256Managed();
                byte[] pbKey32 = sha256.ComputeHash(pbKey);
                byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B,
                    0x97, 0x20, 0x5D, 0x2A }; // Unique constant

                m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
            }
            else // Unknown algorithm
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
        }
Пример #6
0
        private static void TestSalsa20()
        {
            // Test values from official set 6, vector 3
            byte[] pbKey= new byte[32] {
                0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
                0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
                0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
            };
            byte[] pbIV = new byte[8] { 0x28, 0x8F, 0xF6, 0x5D,
                0xC4, 0x2B, 0x92, 0xF9 };
            byte[] pbExpected = new byte[16] {
                0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
                0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
            };

            byte[] pb = new byte[16];
            Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
            c.Encrypt(pb, pb.Length, false);
            if(!MemUtil.ArraysEqual(pb, pbExpected))
                throw new SecurityException("Salsa20.");

            #if DEBUG
            // Extended test in debug mode
            byte[] pbExpected2 = new byte[16] {
                0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
                0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
            };
            byte[] pbExpected3 = new byte[16] {
                0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
                0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
            };

            Random r = new Random();
            int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
            c.Encrypt(pb, pb.Length, false);
            if(!MemUtil.ArraysEqual(pb, pbExpected2))
                throw new SecurityException("Salsa20-2.");

            nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
            Array.Clear(pb, 0, pb.Length);
            c.Encrypt(pb, pb.Length, true);
            if(!MemUtil.ArraysEqual(pb, pbExpected3))
                throw new SecurityException("Salsa20-3.");
            #endif
        }
Пример #7
0
        public static string EncryptData(byte[] pbData, byte[] pbKey32,
			byte[] pbIV16)
        {
            byte[] pbIV8 = new byte[8];
            Array.Copy(pbIV16, 0, pbIV8, 0, 8);

            byte[] pbEnc = new byte[pbData.Length];
            Array.Copy(pbData, pbEnc, pbData.Length);

            Salsa20Cipher enc = new Salsa20Cipher(pbKey32, pbIV8);
            enc.Encrypt(pbEnc, pbEnc.Length, true);

            return ("s20://" + Convert.ToBase64String(pbEnc,
                Base64FormattingOptions.None));
        }
		/// <summary>
		/// Construct a new cryptographically secure random stream object.
		/// </summary>
		/// <param name="genAlgorithm">Algorithm to use.</param>
		/// <param name="pbKey">Initialization key. Must not be <c>null</c> and
		/// must contain at least 1 byte.</param>
		/// <exception cref="System.ArgumentNullException">Thrown if the
		/// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
		/// <exception cref="System.ArgumentException">Thrown if the
		/// <paramref name="pbKey" /> parameter contains no bytes or the
		/// algorithm is unknown.</exception>
		public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
		{
			m_crsAlgorithm = genAlgorithm;

			Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey");

			uint uKeyLen = (uint)pbKey.Length;
			Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException();

			if(genAlgorithm == CrsAlgorithm.ArcFourVariant)
			{
				m_pbState = ComputeArcFourState(pbKey, uKeyLen);

				GetRandomBytes(512); // Increases security, see cryptanalysis
			}
			else if(genAlgorithm == CrsAlgorithm.Salsa20)
			{
				SHA256Managed sha256 = new SHA256Managed();
				byte[] pbKey32 = sha256.ComputeHash(pbKey);
				byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B,
					0x97, 0x20, 0x5D, 0x2A }; // Unique constant

				m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
			}
			else // Unknown algorithm
			{
				Debug.Assert(false);
				throw new ArgumentException();
			}
		}