Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using SharpCore.Framework.DataExtensions;
- using System;
- using System.Collections.Generic;
- using System.Numerics;
- using System.Security.Cryptography;
- using System.Text;
- using System.Linq;
- using SharpCore.Framework.Converters;
- namespace SharpCore.Framework.Cryptography.SRP6
- {
- public class SRP6
- {
- private SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
- private RandomNumberGenerator random = RNGCryptoServiceProvider.Create();
- #region Server side Challenge properties
- public byte[] N { get => Modulus.ToCleanByteArray(); }
- public byte[] B { get => ServerPublicEphemeral.ToCleanByteArray(); }
- public byte[] b { get => ServerPrivateEphemeral.ToCleanByteArray(); }
- public byte[] g { get => Generator.ToCleanByteArray(); }
- public byte[] s { get => Salt.ToCleanByteArray(); }
- public byte[] v { get => Verifier.ToCleanByteArray(); }
- public byte[] A { get => ClientPublicEphemeral.ToCleanByteArray(); }
- public byte[] M1 { get => ClientSessionKeyProof.ToCleanByteArray(); }
- public byte[] M2 { get => ServerSessionKeyProof.ToCleanByteArray(); }
- public byte[] K { get => SessionKeyHash.ToCleanByteArray(); }
- public byte[] S { get => SessionKeyRaw.ToCleanByteArray(); }
- private byte[] I;
- #endregion
- private BigInteger Modulus { get; } = BigInteger.Parse("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", System.Globalization.NumberStyles.HexNumber); // N
- private BigInteger Generator { get; } = new BigInteger(7); // g
- private BigInteger Salt { get; set; } // s
- private BigInteger Verifier { get; set; } // v
- private BigInteger ServerPublicEphemeral { get; set; } // B
- private BigInteger ServerPrivateEphemeral { get; set; } // b
- private BigInteger PrivateKey { get; set; } // x
- private BigInteger Multiplier { get; set; } = new BigInteger(3); //
- private BigInteger Scrambler { get; set; } // u
- private BigInteger SessionKeyRaw { get; set; } // S
- private BigInteger SessionKeyHash { get; set; } // K
- private BigInteger ClientSessionKeyProof { get; set; } // M1
- private BigInteger ServerSessionKeyProof { get; set; } // M2
- private BigInteger ClientPublicEphemeral { get; set; } // A
- public SRP6() { }
- public void Step1(string username = null, string password = null, string salt = null, string verifier = null)
- {
- // Generation de s = RAND()
- if (salt == null)
- CalculateS();
- else
- Salt = BigInteger.Parse("0" + salt, System.Globalization.NumberStyles.HexNumber);
- if (verifier == null)
- CalculateV(username, password);
- else
- Verifier = BigInteger.Parse("0" + verifier, System.Globalization.NumberStyles.HexNumber);
- // Generation de b = RAND()
- byte[] bTmp;
- random.GetBytes(bTmp = new byte[20]);
- ServerPrivateEphemeral = MakeBigInteger(bTmp);
- // Generation de B = kv + g^b % N
- byte[] BTmp = new byte[32];
- BTmp = GetBytes(((Multiplier * Verifier + BigInteger.ModPow(Generator, ServerPrivateEphemeral, Modulus)) % Modulus).ToByteArray());
- ServerPublicEphemeral = MakeBigInteger(BTmp);
- }
- public void CalculateS()
- {
- byte[] sTmp;
- random.GetBytes(sTmp = new byte[32]);
- Salt = MakeBigInteger(sTmp);
- }
- public void CalculateV(string username, string password)
- {
- // Generation de x = H(s | H(P))
- var p = Encoding.UTF8.GetBytes(string.Format("{0}:{1}", username.ToUpper(), password.ToUpper()));
- PrivateKey = MakeBigInteger(sha1.ComputeHash(CombineData(s, sha1.ComputeHash(p))));
- // Generation de v = g ^ x % N
- Verifier = BigInteger.ModPow(Generator, PrivateKey, Modulus);
- }
- public void CalculateU(byte[] A)
- {
- ClientPublicEphemeral = MakeBigInteger(A);
- // Generation de u = H(A | B)
- byte[] u = sha1.ComputeHash(CombineData(A, B));
- Scrambler = MakeBigInteger(u);
- }
- public void CalculateK()
- {
- // Generation de S = (A * v^u) ^ b % N
- BigInteger p1 = ClientPublicEphemeral * BigInteger.ModPow(Verifier, Scrambler, Modulus); // (A * v^u)
- byte[] ss = BigInteger.ModPow(p1, ServerPrivateEphemeral, Modulus).ToByteArray();
- SessionKeyRaw = MakeBigInteger(ss);
- // Generation de K
- byte[] t1 = new byte[16];
- byte[] vK = new byte[40];
- for (int i = 0; i < 16; i++)
- {
- t1[i] = ss[i * 2];
- }
- t1 = sha1.ComputeHash(t1, 0, 16);
- for (int i = 0; i < 20; i++)
- {
- vK[i * 2] = t1[i];
- }
- for (int i = 0; i < 16; i++)
- {
- t1[i] = ss[i * 2 + 1];
- }
- t1 = sha1.ComputeHash(t1, 0, 16);
- for (int i = 0; i < 20; i++)
- {
- vK[i * 2 + 1] = t1[i];
- }
- SessionKeyHash = MakeBigInteger(vK);
- }
- public void CalculateM1(string username)
- {
- // Generation de M1 = H(H(N) xOR H(g), H(I), s, A, B, K)
- byte[] HN = sha1.ComputeHash(N);
- byte[] Hg = sha1.ComputeHash(g);
- byte[] HI = sha1.ComputeHash(Encoding.UTF8.GetBytes(username.StringToHex()));
- for (int i = 0; i < HN.Length; i++)
- HN[i] ^= Hg[i];
- byte[] m1 = sha1.ComputeHash(CombineData(HN, HI, s, A, B, K));
- ClientSessionKeyProof = MakeBigInteger(m1);
- }
- public void CalculateM2(byte[] m1)
- {
- // Generation de M2 = H(A | M1 | K)
- byte[] m2 = sha1.ComputeHash(CombineData(A, m1, K));
- ServerSessionKeyProof = MakeBigInteger(m2);
- }
- #region Helpers
- private byte[] GetBytes(byte[] data, int count = 32)
- {
- if (data.Length <= count)
- return data;
- var bytes = new byte[count];
- Buffer.BlockCopy(data, 0, bytes, 0, count);
- return bytes;
- }
- private BigInteger MakeBigInteger(byte[] data)
- {
- return new BigInteger(CombineData(data, new byte[] { 0 }));
- }
- private byte[] CombineData(byte[] data, byte[] data2)
- {
- return new byte[0].Concat(data).Concat(data2).ToArray();
- }
- private byte[] CombineData(byte[] data, byte[] data2, byte[] data3)
- {
- return new byte[0].Concat(data).Concat(data2).Concat(data3).ToArray();
- }
- private byte[] CombineData(byte[] data, byte[] data2, byte[] data3, byte[] data4)
- {
- return new byte[0].Concat(data).Concat(data2).Concat(data3).Concat(data4).ToArray();
- }
- private byte[] CombineData(byte[] data, byte[] data2, byte[] data3, byte[] data4, byte[] data5, byte[] data6)
- {
- return new byte[0].Concat(data).Concat(data2).Concat(data3).Concat(data4).Concat(data5).Concat(data6).ToArray();
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement