Advertisement
Guest User

Untitled

a guest
Jul 31st, 2017
672
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.48 KB | None | 0 0
  1. using SharpCore.Framework.DataExtensions;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Numerics;
  5. using System.Security.Cryptography;
  6. using System.Text;
  7. using System.Linq;
  8. using SharpCore.Framework.Converters;
  9.  
  10. namespace SharpCore.Framework.Cryptography.SRP6
  11. {
  12.     public class SRP6
  13.     {
  14.         private SHA1CryptoServiceProvider _sha1CSP = new SHA1CryptoServiceProvider();
  15.         private RandomNumberGenerator random = RNGCryptoServiceProvider.Create();
  16.  
  17.         #region Server side Challenge properties
  18.         public byte[] N { get => Modulus.ToCleanByteArray(); }
  19.         public byte[] B { get => ServerPublicEphemeral.ToCleanByteArray(); }
  20.         public byte[] b { get => ServerPrivateEphemeral.ToCleanByteArray(); }
  21.         public byte[] g { get => Generator.ToCleanByteArray(); }
  22.         public byte[] s { get => Salt.ToCleanByteArray(); }
  23.         public byte[] v { get => Verifier.ToCleanByteArray(); }
  24.         public byte[] A { get => ClientPublicEphemeral.ToCleanByteArray(); }
  25.         public byte[] M1 { get => ClientSessionKeyProof.ToCleanByteArray(); }
  26.         public byte[] M2 { get => ServerSessionKeyProof.ToCleanByteArray(); }
  27.         public byte[] K { get => SessionKey.ToCleanByteArray(); }
  28.         private byte[] I;
  29.         #endregion
  30.  
  31.         private BigInteger Modulus { get; } = BigIntegerExtensions.CreateBigInteger("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7", 16); // N
  32.         private BigInteger Generator { get; } = new BigInteger(7); // g
  33.         private BigInteger Salt { get; set; } // s
  34.         private BigInteger Verifier { get; set; } // v
  35.         private BigInteger ServerPublicEphemeral { get; set; } // B
  36.         private BigInteger ServerPrivateEphemeral { get; set; } // b
  37.         private BigInteger PrivateKey { get; set; } // x
  38.         private BigInteger Multiplier { get; set; } = new BigInteger(3); //
  39.         private BigInteger Scrambler { get; set; } // u
  40.         private BigInteger SessionKey { get; set; } // K
  41.         private BigInteger ClientSessionKeyProof { get; set; } // M1
  42.         private BigInteger ServerSessionKeyProof { get; set; } // M2
  43.         private BigInteger ClientPublicEphemeral { get; set; } // A
  44.         private byte[] IdentityHash { get; set; }
  45.  
  46.         public SRP6() { }
  47.  
  48.         public void Step1(string username = null, string password = null, string salt = null, string verifier = null)
  49.         {
  50.             // Generation de s = RAND()
  51.             if (salt == null)
  52.                 CalculateS();
  53.             else
  54.                 Salt = BigInteger.Parse("0" + salt, System.Globalization.NumberStyles.HexNumber);
  55.  
  56.             if (verifier == null)
  57.                 CalculateV(username, password);
  58.             else
  59.                 Verifier = BigInteger.Parse("0" + verifier, System.Globalization.NumberStyles.HexNumber);
  60.  
  61.             // Generation de b = RAND()
  62.             byte[] bTmp;
  63.             random.GetBytes(bTmp = new byte[20]);
  64.             ServerPrivateEphemeral = MakeBigInteger(bTmp);
  65.             // Generation de B = kv + g^b % N
  66.             byte[] BTmp = new byte[32];
  67.             BTmp = GetBytes(((Multiplier * Verifier + BigInteger.ModPow(Generator, ServerPrivateEphemeral, Modulus)) % Modulus).ToByteArray());
  68.             ServerPublicEphemeral = MakeBigInteger(BTmp);
  69.         }
  70.  
  71.         public void CalculateS()
  72.         {
  73.             byte[] sTmp;
  74.             random.GetBytes(sTmp = new byte[32]);
  75.             Salt = MakeBigInteger(sTmp);
  76.         }
  77.  
  78.         public void CalculateV(string username, string password)
  79.         {
  80.             // Generation de x = H(s | H(P))
  81.             var p = Encoding.UTF8.GetBytes(username + ":" + password);
  82.             PrivateKey = MakeBigInteger(SHA1.Create().ComputeHash(CombineData(s, SHA1.Create().ComputeHash(p))));
  83.             // Generation de v = g ^ x % N
  84.             Verifier = BigInteger.ModPow(Generator, PrivateKey, Modulus);
  85.         }
  86.  
  87.         public void CalculateU(byte[] A)
  88.         {
  89.             ClientPublicEphemeral = MakeBigInteger(A);
  90.             // Generation de u = H(A | B)
  91.             byte[] u = SHA1.Create().ComputeHash(CombineData(A, B));
  92.             Scrambler = MakeBigInteger(u);
  93.         }
  94.  
  95.         public void CalculateK()
  96.         {
  97.             // Generation de S = (A * v^u) ^ b % N
  98.             BigInteger p1 = ClientPublicEphemeral * BigInteger.ModPow(Verifier, Scrambler, Modulus); // (A * v^u)
  99.             byte[] ss = BigInteger.ModPow(p1, ServerPrivateEphemeral, Modulus).ToByteArray();
  100.  
  101.             // Generation de K
  102.             byte[] t = new byte[32];
  103.             Buffer.BlockCopy(ss, 0, t, 0, ss.Length);
  104.             byte[] t1 = new byte[16];
  105.             byte[] vK = new byte[40];
  106.  
  107.             for (int i = 0; i < 16; i++)
  108.             {
  109.                 t1[i] = t[i * 2];
  110.             }
  111.  
  112.             t1 = SHA1.Create().ComputeHash(t1, 0, 16);
  113.  
  114.             for (int i = 0; i < 20; i++)
  115.             {
  116.                 vK[i * 2] = t1[i];
  117.             }
  118.  
  119.             for (int i = 0; i < 16; i++)
  120.             {
  121.                 t1[i] = t[i * 2 + 1];
  122.             }
  123.  
  124.             t1 = SHA1.Create().ComputeHash(t1, 0, 16);
  125.  
  126.             for (int i = 0; i < 20; i++)
  127.             {
  128.                 vK[i * 2 + 1] = t1[i];
  129.             }
  130.  
  131.             SessionKey = MakeBigInteger(vK);
  132.         }
  133.  
  134.         public void CalculateM1(string username)
  135.         {
  136.             // Generation de M1
  137.             //Client -> Serveur : M = H(H(N) xor H(g), H(I), s, A, B, K)  (xor correspond au OU exclusif)
  138.             //Serveur->Client : H(A, M, K)
  139.             byte[] HN = SHA1.Create().ComputeHash(N);
  140.             byte[] Hg = SHA1.Create().ComputeHash(g);
  141.             byte[] HI = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(username));
  142.  
  143.             for (int i = 0; i < HN.Length; i++)
  144.                 HN[i] ^= Hg[i];
  145.  
  146.             byte[] m1 = SHA1.Create().ComputeHash(CombineData(HN, HI, s, A, B, K));
  147.             ClientSessionKeyProof = MakeBigInteger(m1);
  148.         }
  149.  
  150.         public void CalculateM2(byte[] m1)
  151.         {
  152.             // Generation de M2 = H(A | M1 | K)
  153.             byte[] m2 = SHA1.Create().ComputeHash(CombineData(A, m1, K));
  154.             ServerSessionKeyProof = MakeBigInteger(m2);
  155.         }
  156.  
  157.        #region Helpers
  158.         private byte[] GetBytes(byte[] data, int count = 32)
  159.         {
  160.             if (data.Length <= count)
  161.                 return data;
  162.  
  163.             var bytes = new byte[count];
  164.  
  165.             Buffer.BlockCopy(data, 0, bytes, 0, count);
  166.  
  167.             return bytes;
  168.         }
  169.  
  170.         private BigInteger MakeBigInteger(byte[] data)
  171.         {
  172.             return new BigInteger(CombineData(data, new byte[] { 0 }));
  173.         }
  174.  
  175.         private byte[] CombineData(byte[] data, byte[] data2)
  176.         {
  177.             return new byte[0].Concat(data).Concat(data2).ToArray();
  178.         }
  179.  
  180.         private byte[] CombineData(byte[] data, byte[] data2, byte[] data3)
  181.         {
  182.             return new byte[0].Concat(data).Concat(data2).Concat(data3).ToArray();
  183.         }
  184.  
  185.         private byte[] CombineData(byte[] data, byte[] data2, byte[] data3, byte[] data4)
  186.         {
  187.             return new byte[0].Concat(data).Concat(data2).Concat(data3).Concat(data4).ToArray();
  188.         }
  189.  
  190.         private byte[] CombineData(byte[] data, byte[] data2, byte[] data3, byte[] data4, byte[] data5, byte[] data6)
  191.         {
  192.             return new byte[0].Concat(data).Concat(data2).Concat(data3).Concat(data4).Concat(data5).Concat(data6).ToArray();
  193.         }
  194.         #endregion
  195.     }
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement