- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
- using System.Security.Cryptography;
- namespace Framework.Cryptography
- {
- public class SRP6
- {
- static HashAlgorithm hashAlgorithm = new SHA1Managed();
- IntPtr BNA, BNa, BNb, BNB, BNg, BNk, BNn, BNS, BNU, BNv, BNx;
- public byte[] K, M, N, S, salt, U;
- public byte[] A = new byte[0x20];
- public byte[] a = new byte[0x14];
- public byte[] b = new byte[0x14];
- public byte[] B = new byte[0x20];
- public byte[] g = new byte[] { 0x07 };
- public byte[] k = new byte[] { 0x03 };
- public string Username, Password;
- public SRP6()
- {
- N = new byte[] { 0x89, 0x4B, 0x64, 0x5E, 0x89, 0xE1, 0x53, 0x5B, 0xBD, 0xAD, 0x5B, 0x8B, 0x29, 0x06, 0x50, 0x53,
- 0x08, 0x01, 0xB1, 0x8E, 0xBF, 0xBF, 0x5E, 0x8F, 0xAB, 0x3C, 0x82, 0x87, 0x2A, 0x3E, 0x9B, 0xB7 };
- }
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_add(IntPtr r, IntPtr a, IntPtr b);
- [DllImport("libeay32.dll", EntryPoint = "BN_bin2bn", CallingConvention = CallingConvention.Cdecl)]
- private static extern IntPtr BN_Bin2BN(byte[] ByteArrayIn, int length, IntPtr to);
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_bn2bin(IntPtr a, byte[] to);
- [DllImport("libeay32.dll", EntryPoint = "BN_CTX_free", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_ctx_free(IntPtr a);
- [DllImport("libeay32.dll", EntryPoint = "BN_CTX_new", CallingConvention = CallingConvention.Cdecl)]
- private static extern IntPtr BN_ctx_new();
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_div(IntPtr dv, IntPtr r, IntPtr a, IntPtr b, IntPtr ctx);
- [DllImport("libeay32.dll", EntryPoint = "BN_free", CallingConvention = CallingConvention.Cdecl)]
- private static extern void BN_Free(IntPtr r);
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern IntPtr BN_mod_exp(IntPtr res, IntPtr a, IntPtr p, IntPtr m, IntPtr ctx);
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_mul(IntPtr r, IntPtr a, IntPtr b, IntPtr ctx);
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- private static extern int BN_sub(IntPtr r, IntPtr a, IntPtr b);
- [DllImport("libeay32.dll", EntryPoint = "BN_new", CallingConvention=CallingConvention.Cdecl)]
- private static extern IntPtr BN_New();
- public void SetB(byte[] data)
- {
- this.B = data;
- Array.Reverse(this.B);
- this.BNB = BN_Bin2BN(this.B, this.B.Length, IntPtr.Zero);
- Array.Reverse(this.B);
- }
- public void CalculateG()
- {
- Array.Reverse(this.g);
- this.BNg = BN_Bin2BN(this.g, this.g.Length, IntPtr.Zero);
- Array.Reverse(this.g);
- }
- public void CalculateN()
- {
- Array.Reverse(this.N);
- this.BNn = BN_Bin2BN(this.N, this.N.Length, IntPtr.Zero);
- Array.Reverse(this.N);
- }
- public void Calculatek()
- {
- Array.Reverse(this.k);
- this.BNk = BN_Bin2BN(this.k, this.k.Length, IntPtr.Zero);
- Array.Reverse(this.k);
- }
- public void CalculateA()
- {
- RAND_bytes(this.a, 20);
- Array.Reverse(this.a);
- this.BNa = BN_Bin2BN(this.a, this.a.Length, IntPtr.Zero);
- Array.Reverse(this.a);
- IntPtr res = BN_New();
- IntPtr r = BN_New();
- IntPtr ptr3 = BN_New();
- this.BNA = BN_New();
- IntPtr ctx = BN_ctx_new();
- BN_mod_exp(res, this.BNg, this.BNa, this.BNn, ctx);
- BN_mul(r, this.BNk, this.BNv, ctx);
- BN_add(ptr3, res, r);
- BN_div(IntPtr.Zero, this.BNA, ptr3, this.BNn, ctx);
- BN_bn2bin(this.BNA, this.A);
- Array.Reverse(this.A);
- BN_ctx_free(ctx);
- BN_Free(ptr3);
- BN_Free(r);
- BN_Free(res);
- }
- public void CalculateK()
- {
- ArrayList list = Split(this.S);
- list[0] = hashAlgorithm.ComputeHash((byte[])list[0]);
- list[1] = hashAlgorithm.ComputeHash((byte[])list[1]);
- this.K = Combine((byte[])list[0], (byte[])list[1]);
- }
- public void CalculateM()
- {
- byte[] dst = new byte[this.S.Length + this.A.Length + this.B.Length + this.K.Length];
- Buffer.BlockCopy(this.S, 0, dst, 0, this.S.Length);
- Buffer.BlockCopy(this.A, 0, dst, this.S.Length, this.A.Length);
- Buffer.BlockCopy(this.B, 0, dst, this.S.Length + this.A.Length, this.B.Length);
- Buffer.BlockCopy(this.K, 0, dst, this.S.Length + this.A.Length + this.B.Length, this.K.Length);
- this.M = hashAlgorithm.ComputeHash(dst);
- }
- public void CalculateS()
- {
- IntPtr res = BN_New();
- IntPtr r = BN_New();
- IntPtr r1 = BN_New();
- IntPtr r2 = BN_New();
- IntPtr r3 = BN_New();
- IntPtr r4 = BN_New();
- IntPtr r5 = BN_New();
- this.BNS = BN_New();
- IntPtr ctx = BN_ctx_new();
- this.S = new byte[0x20];
- BN_mod_exp(res, this.BNg, this.BNx, this.BNn, ctx);
- BN_div(IntPtr.Zero, r, res, this.BNn, ctx);
- BN_mul(r1, this.BNk, res, ctx);
- BN_sub(r2, this.BNB, r1);
- BN_mul(r3, this.BNU, this.BNx, ctx);
- BN_add(r4, this.BNa, r3);
- BN_mod_exp(r5, r2, r4, this.BNn, ctx);
- BN_div(IntPtr.Zero, this.BNS, r5, this.BNn, ctx);
- BN_bn2bin(this.BNS, this.S);
- Array.Reverse(this.S);
- BN_ctx_free(ctx);
- BN_Free(r);
- BN_Free(r1);
- BN_Free(r2);
- BN_Free(r3);
- BN_Free(r4);
- BN_Free(r5);
- BN_Free(res);
- }
- public void CalculateU()
- {
- byte[] dst = new byte[this.A.Length + this.B.Length];
- Buffer.BlockCopy(this.A, 0, dst, 0, this.A.Length);
- Buffer.BlockCopy(this.B, 0, dst, a.Length, this.B.Length);
- this.U = hashAlgorithm.ComputeHash(dst);
- Array.Reverse(this.U);
- this.BNU = BN_Bin2BN(this.U, this.U.Length, IntPtr.Zero);
- Array.Reverse(this.U);
- }
- public void CalculateV()
- {
- this.BNv = BN_New();
- IntPtr ctx = BN_ctx_new();
- BN_mod_exp(this.BNv, this.BNg, this.BNx, this.BNn, ctx);
- BN_ctx_free(ctx);
- }
- public void CalculateX(byte[] username, byte[] password)
- {
- byte[] dst = new byte[this.salt.Length + password.Length];
- Buffer.BlockCopy(this.salt, 0, dst, 0, this.salt.Length);
- Buffer.BlockCopy(password, 0, dst, this.salt.Length, password.Length);
- byte[] buffer5 = hashAlgorithm.ComputeHash(dst, 0, dst.Length);
- Array.Reverse(buffer5);
- this.BNx = BN_Bin2BN(buffer5, buffer5.Length, IntPtr.Zero);
- }
- private static byte[] Combine(byte[] b1, byte[] b2)
- {
- if (b1.Length != b2.Length)
- {
- return null;
- }
- byte[] buffer = new byte[b1.Length + b2.Length];
- int index = 0;
- int num2 = 1;
- for (int i = 0; i < b1.Length; i++)
- {
- buffer[index] = b1[i];
- index++;
- index++;
- }
- for (int j = 0; j < b2.Length; j++)
- {
- buffer[num2] = b2[j];
- num2++;
- num2++;
- }
- return buffer;
- }
- ~SRP6()
- {
- BN_Free(this.BNA);
- BN_Free(this.BNb);
- BN_Free(this.BNB);
- BN_Free(this.BNg);
- BN_Free(this.BNk);
- BN_Free(this.BNn);
- BN_Free(this.BNS);
- BN_Free(this.BNU);
- BN_Free(this.BNv);
- BN_Free(this.BNx);
- }
- [DllImport("libeay32.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern int RAND_bytes(byte[] buf, int num);
- private static ArrayList Split(byte[] bo)
- {
- byte[] dst = new byte[bo.Length - 1];
- if (((bo.Length % 2) != 0) && (bo.Length > 2))
- {
- Buffer.BlockCopy(bo, 1, dst, 0, bo.Length);
- }
- byte[] buffer2 = new byte[bo.Length / 2];
- byte[] buffer3 = new byte[bo.Length / 2];
- int index = 0;
- int num2 = 1;
- for (int i = 0; i < buffer2.Length; i++)
- {
- buffer2[i] = bo[index];
- index++;
- index++;
- }
- for (int j = 0; j < buffer3.Length; j++)
- {
- buffer3[j] = bo[num2];
- num2++;
- num2++;
- }
- ArrayList list = new ArrayList();
- list.Add(buffer2);
- list.Add(buffer3);
- return list;
- }
- }
- }