public static bool Decrypt(ref byte[] buffer, int position, int length) { if (length - position != 128) { return(false); } byte[] temp = new byte[128]; Array.Copy(buffer, position, temp, 0, 128); BigInteger input = new BigInteger(temp); BigInteger output; BigInteger m1 = input.modPow(otServerDP, otServerP); BigInteger m2 = input.modPow(otServerDQ, otServerQ); BigInteger h; if (m2 > m1) { h = otServerP - ((m2 - m1) * otServerInverseQ % otServerP); output = m2 + otServerQ * h; } else { h = (m1 - m2) * otServerInverseQ % otServerP; output = m2 + otServerQ * h; } Array.Copy(GetPaddedValue(output), 0, buffer, position, 128); return(true); }
private static BigInteger findRandomGenerator(BigInteger order, BigInteger modulo, Rng random) { BigInteger one = new BigInteger(1); BigInteger aux = modulo - new BigInteger(1); BigInteger t = aux % order; BigInteger generator; if (t.LongValue() != 0) { return(null); } t = aux / order; while (true) { generator = new BigInteger(); generator.genRandomBits(modulo.bitCount(), random); generator = generator % modulo; generator = generator.modPow(t, modulo); if (generator != one) { break; } } aux = generator.modPow(order, modulo); if (aux != one) { return(null); } return(generator); }
/// <summary> /// Generates the server request and return the A key. /// </summary> public String GenerateRequest() { a = BigInteger.genPseudoPrime(256, 30, new Random()); A = g.modPow(a, p); return(A.ToHexString()); }
public static string RSACRTde(string data, string p, string q, string dp, string dq, string invq) { data = ConvertTool.RemoveSpace(data); p = ConvertTool.RemoveSpace(p); q = ConvertTool.RemoveSpace(q); dp = ConvertTool.RemoveSpace(dp); dq = ConvertTool.RemoveSpace(dq); invq = ConvertTool.RemoveSpace(invq); BigInteger cipher = new BigInteger(ConvertTool.String2Bytes(data)); BigInteger rsaP = new BigInteger(ConvertTool.String2Bytes(p)); BigInteger rsaQ = new BigInteger(ConvertTool.String2Bytes(q)); BigInteger rsaDP = new BigInteger(ConvertTool.String2Bytes(dp)); BigInteger rsaDQ = new BigInteger(ConvertTool.String2Bytes(dq)); BigInteger rsaINVQ = new BigInteger(ConvertTool.String2Bytes(invq)); BigInteger m, m1, m2, h; m1 = cipher.modPow(rsaDP, rsaP); m2 = cipher.modPow(rsaDQ, rsaQ); var temp = m1 - m2; while (temp < 0) { temp += rsaP; } h = (rsaINVQ * temp) % rsaP; m = m2 + (h * rsaQ); return(m.ToHexString()); }
public static RealmPacket CreateAuthResponse(String name, String password) { SHA1 sha = new SHA1CryptoServiceProvider(); byte[] user_pass = System.Text.Encoding.UTF8.GetBytes(((name + ":" + password).ToCharArray())); byte[] hash = sha.ComputeHash(user_pass); byte[] salt = new byte[32]; new Random().NextBytes(salt); byte[] result = new byte[hash.Length + salt.Length]; hash.CopyTo(result, 0); salt.CopyTo(result, hash.Length); byte[] finalhash = sha.ComputeHash(result); byte[] rand = new byte[20]; new Random().NextBytes(rand); //BigInteger int_a = new BigInteger(reverse(finalhash)); //BigInteger int_b = new BigInteger(reverse(N)); BigInteger int_c = new BigInteger(new Byte[] { 7 }); BigInteger int_d = int_c.modPow(new BigInteger(reverse(finalhash)), new BigInteger(reverse(N))); BigInteger K = new BigInteger(new Byte[] { 3 }); BigInteger temp = ((K * int_d) + int_c.modPow(new BigInteger(reverse(rand)), new BigInteger(reverse(N)))) % new BigInteger(reverse(N)); RealmPacket response = new RealmPacket(); response.opcode = RealmOpcode.RS_AUTH_LOGON_CHALLENGE; response.Data.Add(RealmData.RD_AUTH_ERROR, 0); response.Data.Add(RealmData.RD_AUTH_HASH, temp.getBytes()); response.Data.Add(RealmData.RD_AUTH_SALT, salt); response.Data.Add(RealmData.RD_AUTH_N, N); return(response); }
BigInteger GetKeyExchange() { if (exchangeKey == Two) { exchangeKey = Two.modPow(privateKey, N); } return(exchangeKey); }
///Encrypts plaintext m. Ciphertext em = g^m * r^n mod n^2. ///<param name="m">plaintext</param> ///<returns>ciphertext em</returns> public BigInteger Encryption(BigInteger m) { //generates random input r BigInteger r = m.genCoPrime(bitLength, new Random()); BigInteger em = ((g.modPow(m, nsqr)) * (r.modPow(n, nsqr))) % nsqr; return(em); }
public virtual string computeVerifier(string account, string password, string salt) { BigInteger x = getUserHash(account, password, salt); BigInteger verifier = generator.modPow(x, prime); byte[] result = verifier.ToByteArray(); return(getHex(result)); }
static SRP() { // initialize N { NHex = //512bit //"D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43"; //256bit "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3".ToLowerInvariant(); N = new BigInteger(NHex, 16); _nbits = N.bitCount(); Nminus1 = N - 1; // if (!N.isProbablePrime(80)) // { // throw new Exception("Warning: N is not prime"); // } // // if (!(Nminus1 / 2).isProbablePrime(80)) // { // throw new Exception("Warning: (N-1)/2 is not prime"); // } } // initialize g { gHex = "2"; g = new BigInteger(gHex, 16); } // initialize k = H(N || g) { BigInteger ktmp = new BigInteger(HHex( (((NHex.Length & 1) == 0) ? "" : "0") + NHex + new string('0', NHex.Length - gHex.Length) + gHex ), 16); k = (ktmp < N) ? ktmp : (ktmp % N); kHex = k.ToString(16).ToLowerInvariant().TrimStart('0'); } // initialize a, A { a = new BigInteger(); a.genRandomBits(36); A = g.modPow(a, N); while (A.modInverse(N) == 0) { a = new BigInteger(); a.genRandomBits(36); A = g.modPow(a, N); } Ahex = A.ToString(16).ToLowerInvariant().TrimStart('0'); } }
internal void Setup() { _b = new BigInteger(); _b.genRandomBits(256, new Random((int)DateTime.Now.Ticks)); _B = (_k * _v) + (_g.modPow(_b, _N)); while (_B % _N == 0) { _b.genRandomBits(256, new Random((int)DateTime.Now.Ticks)); _B = (_k * _v) + (_g.modPow(_b, _N)); } _Bstr = _B.ToString(16); }
public void TestModPow() { var a = new BigInteger("4513022378190195207248111493619814210011122111521314021116172245292421892189133135249253284210917322371331631915863149241442281401995510735118116112172202199102116124234501111031274954151507124570516154178228146", 10); var n = new BigInteger("2529589762471071921217177179249254145111191246515169611931940652006643560213582062372288573701152271112332092452431128143210751781625037196701031611573185126122233723864211061301331715378213129937", 10); var modulus = new BigInteger(1000000007); var res = a.modPow(n, modulus); Assert.AreEqual(868041175, res.LongValue()); modulus = new BigInteger("922305412110716620326228851918622717821243928922818234109110014149250211422482", 10); res = a.modPow(n, modulus); Assert.AreEqual(new BigInteger("676144631297564803799040568236788209319025642240115630978591468748134664779002", 10), res); }
protected override byte[] ProcessDataBlock(byte[] p_block) { // extract the byte arrays that represent A and B byte[] x_a_bytes = new byte[o_ciphertext_blocksize / 2]; Array.Copy(p_block, 0, x_a_bytes, 0, x_a_bytes.Length); byte[] x_b_bytes = new Byte[o_ciphertext_blocksize / 2]; Array.Copy(p_block, x_a_bytes.Length, x_b_bytes, 0, x_b_bytes.Length); // create big integers from the byte arrays BigInteger A = new BigInteger(x_a_bytes); BigInteger B = new BigInteger(x_b_bytes); // calculate the value M BigInteger M = (B * A.modPow(o_key_struct.X, o_key_struct.P).modInverse(o_key_struct.P)) % o_key_struct.P; // return the result - take care to ensure that we create // a result which is the correct length byte[] x_m_bytes = M.getBytes(); // we may end up with results which are short some leading // bytes - add these are required if (x_m_bytes.Length < o_plaintext_blocksize) { byte[] x_full_result = new byte[o_plaintext_blocksize]; Array.Copy(x_m_bytes, 0, x_full_result, o_plaintext_blocksize - x_m_bytes.Length, x_m_bytes.Length); x_m_bytes = x_full_result; } return(x_m_bytes); }
// Calculate S, M, and M2 // This is the server side of the SRP specification private Error Calculations(string Astr, BigInteger v) { BigInteger A = new BigInteger(Astr, 16); // u = H(A,B) BigInteger u = new BigInteger(Utils.Hash(Astr + this.Bstr)); if (u == 0) { return(new Error(ErrorCode.AUTH_INVALID_PARAM)); } //S = (Av^u) ^ b BigInteger Avu = A * (v.modPow(u, N)); this.S = Avu.modPow(b, N); // Calculate the auth hash we will expect from the client (M) and the one we will send back in the next step (M2) // M = H(A, B, S) //M2 = H(A, M, S) string Mstr = A.ToString(16) + this.B.ToString(16) + this.S.ToString(16); this.M = KeePassLib.Utility.MemUtil.ByteArrayToHexString(Utils.Hash(Mstr)); this.M2 = KeePassLib.Utility.MemUtil.ByteArrayToHexString(Utils.Hash(A.ToString(16) + this.M.ToLower() + this.S.ToString(16))); return(new Error(ErrorCode.SUCCESS)); }
private string EncryptString(string source, BigInteger d, BigInteger n) { int len = source.Length; int len1 = 0; if ((len % 128) == 0) { len1 = len / 128; } else { len1 = len / 128 + 1; } string temp = ""; for (int i = 0; i < len1; i++) { var blockLen = 0; blockLen = len >= 128 ? 128 : len; var block = source.Substring(i * 128, blockLen); byte[] oText = Encoding.Default.GetBytes(block); var biText = new BigInteger(oText); var biEnText = biText.modPow(d, n); string temp1 = biEnText.ToHexString(); temp += temp1; len -= blockLen; } return(temp); }
public bool Validate() { BigInteger calculatedHash = new BigInteger(this.ToString(), _RADIX); bool ret = true; //Calculate the hash calculatedHash = calculatedHash.modPow(new BigInteger(17), _n); //Compare our real hash and the calculated hash byte[] ourHash = _hash.getBytes(); byte[] myHash = calculatedHash.getBytes(); if (ourHash.Length == myHash.Length) { for (int i = 0; i <= ourHash.Length - 1; i++) { if (ourHash[i] != myHash[i]) { ret = false; break; // TODO: might not be correct. Was : Exit For } } } else { //Not even the right length, it's crap ret = false; } return ret; }
private static byte[] Compute(byte[] data, RSAPrivateKey privateKey, int blockSize) { // // 私钥加密/解密公式为:mi = ci^d ( mod n ) // // 先将 c(二进制表示)分成数据块 c1, c2, ..., ci ,然后进行运算。 // BigInteger d = new BigInteger(privateKey.D); BigInteger n = new BigInteger(privateKey.Modulus); int blockOffset = 0; using (MemoryStream stream = new MemoryStream()) { while (blockOffset < data.Length) { int blockLen = Math.Min(blockSize, data.Length - blockOffset); byte[] blockData = new byte[blockLen]; Buffer.BlockCopy(data, blockOffset, blockData, 0, blockLen); BigInteger ci = new BigInteger(blockData); BigInteger mi = ci.modPow(d, n);//mi = ci^d ( mod n ) byte[] block = mi.getBytes(); stream.Write(block, 0, block.Length); blockOffset += blockLen; } return(stream.ToArray()); } }
private string DecryptString(string source, BigInteger e, BigInteger n) { int len = source.Length; int len1 = 0; if ((len % 256) == 0) { len1 = len / 256; } else { len1 = len / 256 + 1; } string temp = ""; for (int i = 0; i < len1; i++) { var blockLen = 0; blockLen = len >= 256 ? 256 : len; var block = source.Substring(i * 256, blockLen); var biText = new BigInteger(block, 16); var biEnText = biText.modPow(e, n); string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes()); temp += temp1; len -= blockLen; } return(temp); }
public byte[] Encrypt(byte[] source) { BigInteger d = new BigInteger(paramsters.D); BigInteger n = new BigInteger(paramsters.Modulus); int sug = 127; int len = source.Length; int cycle = 0; if ((len % sug) == 0) cycle = len / sug; else cycle = len / sug + 1; ArrayList temp = new ArrayList(); int blockLen = 0; for (int i = 0; i < cycle; i++) { if (len >= sug) blockLen = sug; else blockLen = len; byte[] context = new byte[blockLen]; int po = i * sug; Array.Copy(source, po, context, 0, blockLen); BigInteger biText = new BigInteger(context); BigInteger biEnText = biText.modPow(d, n); byte[] b = biEnText.getBytes(); temp.AddRange(b); len -= blockLen; } return (byte[])temp.ToArray(typeof(byte)); }
//public static byte[] Encrypt(byte[] data, RSAPrivateKey privateKey) { // if (data == null) { // throw new ArgumentNullException("data"); // } // if (privateKey == null) { // throw new ArgumentNullException("privateKey"); // } // int blockSize = privateKey.Modulus.Length - 1; // return Compute(data, privateKey, blockSize); //} //public static string Encrypt(string data, string privateKey) { // return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(data), RSAPrivateKey.FromXmlString(privateKey))); //} //public static byte[] Decrypt(byte[] data, RSAPublicKey publicKey) { // if (data == null) { // throw new ArgumentNullException("data"); // } // if (publicKey == null) { // throw new ArgumentNullException("publicKey"); // } // int blockSize = publicKey.Modulus.Length; // return Compute(data, publicKey, blockSize); //} //public static string Decrypt(string data, string publicKey) { // return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(data), RSAPublicKey.FromXmlString(publicKey))); //} //public static byte[] Sign(byte[] data, RSAPrivateKey privateKey, HashAlgorithm hash) { // if (data == null) { // throw new ArgumentNullException("data"); // } // if (privateKey == null) { // throw new ArgumentNullException("privateKey"); // } // if (hash == null) { // throw new ArgumentNullException("hash"); // } // byte[] hashData = hash.ComputeHash(data); // byte[] signature = Encrypt(hashData, privateKey); // return signature; //} //public static string Sign(string data, string privateKey, HashAlgorithm hash) { // return Convert.ToBase64String(Sign(Encoding.UTF8.GetBytes(data), RSAPrivateKey.FromXmlString(privateKey), hash)); //} //public static bool Verify(byte[] data, RSAPublicKey publicKey, HashAlgorithm hash, byte[] signature) { // if (data == null) { // throw new ArgumentNullException("data"); // } // if (publicKey == null) { // throw new ArgumentNullException("publicKey"); // } // if (hash == null) { // throw new ArgumentNullException("hash"); // } // if (signature == null) { // throw new ArgumentNullException("signature"); // } // byte[] hashData = hash.ComputeHash(data); // byte[] signatureHashData = Decrypt(signature, publicKey); // if (signatureHashData != null && signatureHashData.Length == hashData.Length) { // for (int i = 0; i < signatureHashData.Length; i++) { // if (signatureHashData[i] != hashData[i]) { // return false; // } // } // return true; // } // return false; //} //public static bool Verify(string data, string publicKey, HashAlgorithm hash, string signature) { // return Verify(Encoding.UTF8.GetBytes(data), RSAPublicKey.FromXmlString(publicKey), hash, Encoding.UTF8.GetBytes(signature)); //} private static byte[] Compute(byte[] data, RSAPublicKey publicKey, int blockSize) { // // 公钥加密/解密公式为:ci = mi^e ( mod n ) // // 先将 m(二进制表示)分成数据块 m1, m2, ..., mi ,然后进行运算。 // BigInteger e = new BigInteger(publicKey.Exponent); BigInteger n = new BigInteger(publicKey.Modulus); int blockOffset = 0; using (MemoryStream stream = new MemoryStream()) { while (blockOffset < data.Length) { int blockLen = Math.Min(blockSize, data.Length - blockOffset); byte[] blockData = new byte[blockLen]; Buffer.BlockCopy(data, blockOffset, blockData, 0, blockLen); BigInteger mi = new BigInteger(blockData); BigInteger ci = mi.modPow(e, n);//ci = mi^e ( mod n ) byte[] block = ci.getBytes(); stream.Write(block, 0, block.Length); blockOffset += blockLen; } return(stream.ToArray()); } }
public byte[] Decrypt(byte[] source) { BigInteger e = new BigInteger(paramsters.Exponent); BigInteger n = new BigInteger(paramsters.Modulus); int bk = 128; int len = source.Length; int cycle = 0; if ((len % bk) == 0) cycle = len / bk; else cycle = len / bk + 1; ArrayList temp = new ArrayList(); int blockLen = 0; for (int i = 0; i < cycle; i++) { if (len >= bk) blockLen = bk; else blockLen = len; byte[] context = new byte[blockLen]; int po = i * bk; Array.Copy(source, po, context, 0, blockLen); BigInteger biText = new BigInteger(context); BigInteger biEnText = biText.modPow(e, n); byte[] b = biEnText.getBytes(); temp.AddRange(b); len -= blockLen; } return (byte[])temp.ToArray(typeof(byte)); }
public static void AuthStep2( string vHex, string uHex, string AHex, string bHex, string BHex, out string m1serverHex, out string m2Hex) { BigInteger v = new BigInteger(vHex, 16); BigInteger u = new BigInteger(uHex, 16); BigInteger A = new BigInteger(AHex, 16); BigInteger b = new BigInteger(bHex, 16); BigInteger B = new BigInteger(BHex, 16); // S - common exponential value // S = (A * v^u) ^ b (mod N) BigInteger S = ((v.modPow(u, N) * A) % N).modPow(b, N); // K - the strong cryptographically session key // K = H(S) string KHex = HHex(S.ToHexString()).TrimStart('0'); // m2 - expected client's proof as computed by the server m1serverHex = HHex( AHex + BHex + KHex).TrimStart('0'); // m2 - server's proof that it has the correct key m2Hex = HHex( AHex + m1serverHex + KHex).TrimStart('0'); }
public static void TestElgamal() { /*Elgamal.cryptFile(593, 123, 8, @"C:\Users\Vladimir\Desktop\Новая папка\Новый текстовый документ (1).txt", @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt"); * Console.WriteLine("crypted"); * Elgamal.decryptFile(593, 8, @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt", @"C:\Users\Vladimir\Desktop\Новая папка\out_decrypt.txt"); * Console.WriteLine("decrypted");*/ BigInteger p = 809; BigInteger g = 3; BigInteger x = 68; BigInteger H = g.modPow(x, p);// Elgamal.power(g, x, p); BigInteger m = 100; BigInteger a; BigInteger b; /*Elgamal.crypt(p, g, H, m, out a, out b); * BigInteger res = Elgamal.decrypt(p, x, a, b); * Console.WriteLine(res);*/ int sizeOfBlock = 1; /*Elgamal.cryptFile(p, g, x, sizeOfBlock, @"C:\Users\Vladimir\Desktop\Новая папка\Новый текстовый документ (1).txt", @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt"); * Console.WriteLine("crypted"); * Elgamal.decryptFile(p, x, sizeOfBlock, @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt", @"C:\Users\Vladimir\Desktop\Новая папка\out_decrypt.txt"); * Console.WriteLine("decrypted");*/ Elgamal.cryptFile(p, g, x, sizeOfBlock, @"C:\Users\Vladimir\Desktop\Новая папка\08140-Kurukafa.jpg", @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt"); Console.WriteLine("crypted"); Elgamal.decryptFile(p, x, sizeOfBlock, @"C:\Users\Vladimir\Desktop\Новая папка\out_crypt.txt", @"C:\Users\Vladimir\Desktop\Новая папка\out_decrypt.jpg"); Console.WriteLine("decrypted"); }
public static void crypt(BigInteger p, BigInteger g, BigInteger y, BigInteger m, out BigInteger a, out BigInteger b) { BigInteger k = (BigInteger)(Rand() % (p - 2) + 1); a = g.modPow(k, p); b = mul(m, y.modPow(k, p), p); }
//функция вычисления квадратоного корня по модулю простого числа q public BigInteger ModSqrt(BigInteger a, BigInteger q) { BigInteger b = new BigInteger(); do { b.genRandomBits(255, new Random()); } while (Legendre(b, q) == 1); BigInteger s = 0; BigInteger t = q - 1; while ((t & 1) != 1) { s++; t = t >> 1; } BigInteger InvA = a.modInverse(q); BigInteger c = b.modPow(t, q); BigInteger r = a.modPow(((t + 1) / 2), q); BigInteger d = new BigInteger(); for (int i = 1; i < s; i++) { BigInteger temp = 2; temp = temp.modPow((s - i - 1), q); d = (r.modPow(2, q) * InvA).modPow(temp, q); if (d == (q - 1)) r = (r * c) % q; c = c.modPow(2, q); } return r; }
private void equal2_Click(object sender, RoutedEventArgs e) { BigInteger n3; BigInteger power; BigInteger n4; if (number3.Text == "" || number4.Text == "") { result2.Text = "Please enter a number and a modulo"; } else { try { n3 = new BigInteger(number3.Text, 10); power = new BigInteger(numberP.Text, 10); n4 = new BigInteger(number4.Text, 10); result2.Text = n3.modPow(power, n4).ToString(); } catch (System.Exception excep) { result2.Text = "Please enter numbers"; } } }
public byte[] GenerateKeyClient(BigInteger key1, BigInteger exchangeKey, string user, string password) { string username = user + "@plaync.co.kr"; byte[] passwordHash = sha.ComputeHash(Encoding.ASCII.GetBytes(username + ":" + password)); BigInteger hash1 = SHA256Hash2ArrayInverse(this.GetKeyExchange().getBytes(), exchangeKey.getBytes()); BigInteger hash2 = SHA256Hash2ArrayInverse(key1.getBytes(), passwordHash); BigInteger v27 = new BigInteger(exchangeKey); BigInteger v25 = Two.modPow(hash2, N); v25 = (v25 * P) % N; while (v27 < v25) { v27 += N; } v27 -= v25; BigInteger v24 = ((hash1 * hash2) + privateKey) % N; BigInteger v21 = v27.modPow(v24, N); encKey = GenerateEncryptionKeyRoot(v21.getBytes()); encKey = Generate256BytesKey(encKey); decKey = new byte[encKey.Length]; encKey.CopyTo(decKey, 0); encCounter = 0; decCounter = 0; return(sha.ComputeHash(CombineBuffers(staticKey, sha.ComputeHash(Encoding.ASCII.GetBytes(username)), key1.getBytes(), this.GetKeyExchange().getBytes(), exchangeKey.getBytes(), encKey))); }
/// <summary> /// 用指定的密匙加密 /// </summary> /// <param name="source">明文</param> /// <param name="d">可以是RSACryptoServiceProvider生成的D</param> /// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param> /// <returns>返回密文</returns> private static string EncryptString(string source, BigInteger d, BigInteger n) { int len = source.Length; int len1 = 0; int blockLen = 0; if ((len % 128) == 0) len1 = len / 128; else len1 = len / 128 + 1; string block = ""; StringBuilder result = new StringBuilder(); for (int i = 0; i < len1; i++) { if (len >= 128) blockLen = 128; else blockLen = len; block = source.Substring(i * 128, blockLen); byte[] oText = System.Text.Encoding.Default.GetBytes(block); BigInteger biText = new BigInteger(oText); BigInteger biEnText = biText.modPow(d, n); string temp = biEnText.ToHexString(); result.Append(temp).Append("@"); len -= blockLen; } return result.ToString().TrimEnd('@'); }
public static BigInteger Crypt(BigInteger x, long y, long n) { var bigY = new BigInteger(y); var bigN = new BigInteger(n); return x.modPow(bigY, bigN); }
/// <summary> /// RSA加密(用私钥加密哟) /// </summary> /// <param name="key">私钥 XML字符串</param> /// <param name="data">待加密的数据</param> /// <returns></returns> public static byte[] RSAEncrypt(String key, byte[] data) { //由密钥xml取得RSA对象 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(key); //取得加密时使用的2个参数 RSAParameters par = rsa.ExportParameters(true); BigInteger mod = new BigInteger(par.Modulus); BigInteger ep = new BigInteger(par.D); //计算填充长度 int mLen = par.Modulus.Length; int fLen = mLen - data.Length - 3; //组建bytes List <byte> lis = new List <byte>(); lis.Add(0x00); lis.Add(0x01);//兼容java for (int i = 0; i < fLen; i++) { lis.Add(0xff); } lis.Add(0x00); lis.AddRange(data); byte[] bytes = lis.ToArray(); //加密就这么简单? BigInteger m = new BigInteger(bytes); BigInteger c = m.modPow(ep, mod); return(c.getBytes()); }
public byte[][] GenerateKeyClient(BigInteger exchangeKey) { string username = user + "@plaync.co.kr"; byte[] passwordHash = sha.ComputeHash(Encoding.ASCII.GetBytes(username + ":" + password)); BigInteger hash1 = SHA256Hash2ArrayInverse(GetKeyExchange().getBytes(), exchangeKey.getBytes()); BigInteger hash2 = SHA256Hash2ArrayInverse(session.getBytes(), passwordHash); BigInteger v27 = new BigInteger(exchangeKey.getBytes()); BigInteger v25 = Two.modPow(hash2, N); v25 = (v25 * P) % N; while (v27 < v25) { v27 += N; } v27 -= v25; BigInteger v24 = ((hash1 * hash2) + privateKey) % N; BigInteger v21 = v27.modPow(v24, N); key = GenerateEncryptionKeyRoot(v21.getBytes()); byte[] chash1 = sha.ComputeHash(CombineBuffers(staticKey, sha.ComputeHash(Encoding.ASCII.GetBytes(username)), session.getBytes(), GetKeyExchange().getBytes(), exchangeKey.getBytes(), key)); byte[] chash2 = sha.ComputeHash(CombineBuffers(GetKeyExchange().getBytes(), chash1, key)); key = Generate256BytesKey(key); return(new byte[][] { chash1, chash2 }); }
//функция вычисления квадратоного корня по модулю простого числа q public BigInteger ModSqrt(BigInteger a, BigInteger q) { BigInteger b = new BigInteger(); do { b.genRandomBits(255, new Random()); } while (Legendre(b, q) == 1); BigInteger s = 0; BigInteger t = q - 1; while ((t & 1) != 1) { s++; t = t >> 1; } BigInteger InvA = a.modInverse(q); BigInteger c = b.modPow(t, q); BigInteger r = a.modPow(((t + 1) / 2), q); BigInteger d = new BigInteger(); for (int i = 1; i < s; i++) { BigInteger temp = 2; temp = temp.modPow((s - i - 1), q); d = (r.modPow(2, q) * InvA).modPow(temp, q); if (d == (q - 1)) { r = (r * c) % q; } c = c.modPow(2, q); } return(r); }
/// <summary> /// RSA解密(用公钥解密哟) /// </summary> /// <param name="key">公钥</param> /// <param name="data">待解密的数据</param> /// <returns></returns> public static byte[] RSADecrypt(String key, byte[] data) { //由密钥xml取得RSA对象 RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.FromXmlString(key); //取得解密时使用的2个参数 RSAParameters par = rsa.ExportParameters(false); BigInteger mod = new BigInteger(par.Modulus); BigInteger ep = new BigInteger(par.Exponent); //解密? BigInteger m = new BigInteger(data); BigInteger c = m.modPow(ep, mod); byte[] bytes = c.getBytes(); //去掉填充域(头部可能填充了一段0xff) byte flag = 0; for (int i = 1 /*我从1开始啦*/; i < bytes.Length; i++) { if (bytes[i] == flag && i != (bytes.Length - 1)) { byte[] retBytes = new byte[bytes.Length - i - 1]; Array.Copy(bytes, i + 1, retBytes, 0, retBytes.Length); return(retBytes); } } return(bytes); }
public void DoHandshake(string SignedPrime, string SignedGenerator) { if (IsInitiator) { return; } byte[] SignedPrimeAsBytes = HexToBytes(SignedPrime); RSA.Verify(ref SignedPrimeAsBytes); byte[] SignedGeneratorAsBytes = HexToBytes(SignedGenerator); RSA.Verify(ref SignedGeneratorAsBytes); DHPrime = new BigInteger(Encoding.Default.GetString(SignedPrimeAsBytes), 10); DHGenerator = new BigInteger(Encoding.Default.GetString(SignedGeneratorAsBytes), 10); if (DHPrime <= 2) { throw new Exception("Prime cannot be <= 2!\nPrime: " + DHPrime.ToString()); } if (DHGenerator >= DHPrime) { throw new Exception(string.Format("Generator cannot be >= Prime!\nPrime: {0}\nGenerator: {1}", DHPrime.ToString(), DHGenerator.ToString())); } DHPrivate = new BigInteger(RandomHex(30), BitSize); DHPublic = DHGenerator.modPow(DHPrivate, DHPrime); }
protected override byte[] ProcessDataBlock(byte[] plaintext_data_block) { // extract the byte arrays that represent A and B byte[] a_bytes = new byte[ciphertext_blocksize / 2]; Array.Copy(plaintext_data_block, 0, a_bytes, 0, a_bytes.Length); byte[] b_bytes = new Byte[ciphertext_blocksize / 2]; Array.Copy(plaintext_data_block, a_bytes.Length, b_bytes, 0, b_bytes.Length); // create big integers from the byte arrays BigInteger A = new BigInteger(a_bytes); BigInteger B = new BigInteger(b_bytes); //c2 * c1 exp X mod p BigInteger M = (B * A.modPow(current_key.X, current_key.P).modInverse(current_key.P)) % current_key.P; // return the result byte[] m_bytes = M.getBytes(); if (m_bytes.Length < plaintext_blocksize) { byte[] full_block_result = new byte[plaintext_blocksize]; Array.Copy(m_bytes, 0, full_block_result, plaintext_blocksize - m_bytes.Length, m_bytes.Length); m_bytes = full_block_result; } return(m_bytes); }
public static BigInteger BI_Generate_Yi( BigInteger argP, BigInteger argG, BigInteger argKi ) { return argG.modPow(argKi, argP); }
public static BigInteger Calculate_Ri( BigInteger argG, BigInteger argP, BigInteger argTi ) { return argG.modPow(argTi, argP); }
public static bool verifySig(BigInteger m, BigInteger s, BigInteger e, BigInteger n) { BigInteger mtest = new BigInteger(s.modPow(e, n)); if (m == mtest) return true; else return false; }
public string EncryptSymmetricKey(string symmKey, BigInteger e, BigInteger n) { BigInteger cryptoSymmKey = new BigInteger(Convert.FromBase64String(symmKey)); cryptoSymmKey = cryptoSymmKey.modPow(e,n); string symmKeyString = Convert.ToBase64String(cryptoSymmKey.getBytes()); return symmKeyString; }
public static BigInteger Calculate_Si( BigInteger argTi, BigInteger argHi, BigInteger argKi, BigInteger argE, BigInteger argQ ) { return (argTi - (argHi.modPow(1, argQ) * argKi.modPow(1, argQ) * argE.modPow(1, argQ)).modPow(1, argQ)); }
public static bool verifySig(BigInteger m, BigInteger s, rsakey rk) { BigInteger e = rk.getk(); BigInteger n = rk.getn(); BigInteger mtest = new BigInteger(s.modPow(e, n)); if (m == mtest) return true; else return false; }
public static bool verifySig(BigInteger m, BigInteger s, BigInteger e, BigInteger n) { // Console.WriteLine("\nE: " + e); // Console.WriteLine("\nN: " + n); BigInteger mtest = new BigInteger(s.modPow(e, n)); // Console.WriteLine("\nM: " + m); // Console.WriteLine("\nMtest: " + mtest); if (m == mtest) return true; else return false; }
public string DecryptSymmetricKey(string encrSymmKey, BigInteger d, BigInteger n) { BigInteger encryptedSymmKey = new BigInteger(Convert.FromBase64String(encrSymmKey)); //can be redone with RSA for efficiency BigInteger decryptedSymmKey = encryptedSymmKey.modPow(d, n); byte[] symmKeyBytes = decryptedSymmKey.getBytes(); string symmKey = Encoding.ASCII.GetString(symmKeyBytes); return symmKey; }
private BigInteger genrecshare(BigInteger Ri, BigInteger x) { BigInteger inverseX = x.modInverse(q); BigInteger Si = new BigInteger(Ri.modPow(inverseX, p)); //to be reviewed //Console.WriteLine("\nSi: " + Si); return Si; }
public static BigInteger createSig(BigInteger m, BigInteger d, BigInteger n) { return m.modPow(d, n); }
public static BigInteger createSig(BigInteger m, rsakey rk) { BigInteger d = rk.getk(); BigInteger n = rk.getn(); return m.modPow(d, n); }
//*********************************************************************** // Tests the correct implementation of the modulo exponential function // using RSA encryption and decryption (using pre-computed encryption and // decryption keys). //*********************************************************************** public static void RSATest(int rounds) { Random rand = new Random(1); byte[] val = new byte[64]; // private and public key BigInteger bi_e = new BigInteger("a932b948feed4fb2b692609bd22164fc9edb59fae7880cc1eaff7b3c9626b7e5b241c27a974833b2622ebe09beb451917663d47232488f23a117fc97720f1e7", 16); BigInteger bi_d = new BigInteger("4adf2f7a89da93248509347d2ae506d683dd3a16357e859a980c4f77a4e2f7a01fae289f13a851df6e9db5adaa60bfd2b162bbbe31f7c8f828261a6839311929d2cef4f864dde65e556ce43c89bbbf9f1ac5511315847ce9cc8dc92470a747b8792d6a83b0092d2e5ebaf852c85cacf34278efa99160f2f8aa7ee7214de07b7", 16); BigInteger bi_n = new BigInteger("e8e77781f36a7b3188d711c2190b560f205a52391b3479cdb99fa010745cbeba5f2adc08e1de6bf38398a0487c4a73610d94ec36f17f3f46ad75e17bc1adfec99839589f45f95ccc94cb2a5c500b477eb3323d8cfab0c8458c96f0147a45d27e45a4d11d54d77684f65d48f15fafcc1ba208e71e921b9bd9017c16a5231af7f", 16); Console.WriteLine("e =\n" + bi_e.ToString(10)); Console.WriteLine("\nd =\n" + bi_d.ToString(10)); Console.WriteLine("\nn =\n" + bi_n.ToString(10) + "\n"); for(int count = 0; count < rounds; count++) { // generate data of random length int t1 = 0; while(t1 == 0) t1 = (int)(rand.NextDouble() * 65); bool done = false; while(!done) { for(int i = 0; i < 64; i++) { if(i < t1) val[i] = (byte)(rand.NextDouble() * 256); else val[i] = 0; if(val[i] != 0) done = true; } } while(val[0] == 0) val[0] = (byte)(rand.NextDouble() * 256); Console.Write("Round = " + count); // encrypt and decrypt data BigInteger bi_data = new BigInteger(val, t1); BigInteger bi_encrypted = bi_data.modPow(bi_e, bi_n); BigInteger bi_decrypted = bi_encrypted.modPow(bi_d, bi_n); // compare if(bi_decrypted != bi_data) { Console.WriteLine("\nError at round " + count); Console.WriteLine(bi_data + "\n"); return; } Console.WriteLine(" <PASSED>."); } }
//*********************************************************************** // Tests the correct implementation of the modulo exponential and // inverse modulo functions using RSA encryption and decryption. The two // pseudoprimes p and q are fixed, but the two RSA keys are generated // for each round of testing. //*********************************************************************** public static void RSATest2(int rounds) { Random rand = new Random(); byte[] val = new byte[64]; byte[] pseudoPrime1 = { (byte)0x85, (byte)0x84, (byte)0x64, (byte)0xFD, (byte)0x70, (byte)0x6A, (byte)0x9F, (byte)0xF0, (byte)0x94, (byte)0x0C, (byte)0x3E, (byte)0x2C, (byte)0x74, (byte)0x34, (byte)0x05, (byte)0xC9, (byte)0x55, (byte)0xB3, (byte)0x85, (byte)0x32, (byte)0x98, (byte)0x71, (byte)0xF9, (byte)0x41, (byte)0x21, (byte)0x5F, (byte)0x02, (byte)0x9E, (byte)0xEA, (byte)0x56, (byte)0x8D, (byte)0x8C, (byte)0x44, (byte)0xCC, (byte)0xEE, (byte)0xEE, (byte)0x3D, (byte)0x2C, (byte)0x9D, (byte)0x2C, (byte)0x12, (byte)0x41, (byte)0x1E, (byte)0xF1, (byte)0xC5, (byte)0x32, (byte)0xC3, (byte)0xAA, (byte)0x31, (byte)0x4A, (byte)0x52, (byte)0xD8, (byte)0xE8, (byte)0xAF, (byte)0x42, (byte)0xF4, (byte)0x72, (byte)0xA1, (byte)0x2A, (byte)0x0D, (byte)0x97, (byte)0xB1, (byte)0x31, (byte)0xB3, }; byte[] pseudoPrime2 = { (byte)0x99, (byte)0x98, (byte)0xCA, (byte)0xB8, (byte)0x5E, (byte)0xD7, (byte)0xE5, (byte)0xDC, (byte)0x28, (byte)0x5C, (byte)0x6F, (byte)0x0E, (byte)0x15, (byte)0x09, (byte)0x59, (byte)0x6E, (byte)0x84, (byte)0xF3, (byte)0x81, (byte)0xCD, (byte)0xDE, (byte)0x42, (byte)0xDC, (byte)0x93, (byte)0xC2, (byte)0x7A, (byte)0x62, (byte)0xAC, (byte)0x6C, (byte)0xAF, (byte)0xDE, (byte)0x74, (byte)0xE3, (byte)0xCB, (byte)0x60, (byte)0x20, (byte)0x38, (byte)0x9C, (byte)0x21, (byte)0xC3, (byte)0xDC, (byte)0xC8, (byte)0xA2, (byte)0x4D, (byte)0xC6, (byte)0x2A, (byte)0x35, (byte)0x7F, (byte)0xF3, (byte)0xA9, (byte)0xE8, (byte)0x1D, (byte)0x7B, (byte)0x2C, (byte)0x78, (byte)0xFA, (byte)0xB8, (byte)0x02, (byte)0x55, (byte)0x80, (byte)0x9B, (byte)0xC2, (byte)0xA5, (byte)0xCB, }; BigInteger bi_p = new BigInteger(pseudoPrime1); BigInteger bi_q = new BigInteger(pseudoPrime2); BigInteger bi_pq = (bi_p-1)*(bi_q-1); BigInteger bi_n = bi_p * bi_q; for(int count = 0; count < rounds; count++) { // generate private and public key BigInteger bi_e = bi_pq.genCoPrime(512, rand); BigInteger bi_d = bi_e.modInverse(bi_pq); Console.WriteLine("\ne =\n" + bi_e.ToString(10)); Console.WriteLine("\nd =\n" + bi_d.ToString(10)); Console.WriteLine("\nn =\n" + bi_n.ToString(10) + "\n"); // generate data of random length int t1 = 0; while(t1 == 0) t1 = (int)(rand.NextDouble() * 65); bool done = false; while(!done) { for(int i = 0; i < 64; i++) { if(i < t1) val[i] = (byte)(rand.NextDouble() * 256); else val[i] = 0; if(val[i] != 0) done = true; } } while(val[0] == 0) val[0] = (byte)(rand.NextDouble() * 256); Console.Write("Round = " + count); // encrypt and decrypt data BigInteger bi_data = new BigInteger(val, t1); BigInteger bi_encrypted = bi_data.modPow(bi_e, bi_n); BigInteger bi_decrypted = bi_encrypted.modPow(bi_d, bi_n); // compare if(bi_decrypted != bi_data) { Console.WriteLine("\nError at round " + count); Console.WriteLine(bi_data + "\n"); return; } Console.WriteLine(" <PASSED>."); } }
public static RealmPacket CreateAuthResponse(String name, String password) { SHA1 sha = new SHA1CryptoServiceProvider(); byte[] user_pass = System.Text.Encoding.UTF8.GetBytes(((name + ":" + password).ToCharArray())); byte[] hash = sha.ComputeHash(user_pass); byte[] salt = new byte[32]; new Random().NextBytes(salt); byte[] result = new byte[hash.Length + salt.Length]; hash.CopyTo(result, 0); salt.CopyTo(result, hash.Length); byte[] finalhash = sha.ComputeHash(result); byte[] rand = new byte[20]; new Random().NextBytes(rand); //BigInteger int_a = new BigInteger(reverse(finalhash)); //BigInteger int_b = new BigInteger(reverse(N)); BigInteger int_c = new BigInteger(new Byte[] { 7 }); BigInteger int_d = int_c.modPow(new BigInteger(reverse(finalhash)),new BigInteger(reverse(N))); BigInteger K = new BigInteger(new Byte[] { 3 }); BigInteger temp = ((K * int_d) + int_c.modPow(new BigInteger(reverse(rand)), new BigInteger(reverse(N)))) % new BigInteger(reverse(N)); RealmPacket response = new RealmPacket(); response.opcode = RealmOpcode.RS_AUTH_LOGON_CHALLENGE; response.Data.Add(RealmData.RD_AUTH_ERROR, 0); response.Data.Add(RealmData.RD_AUTH_HASH, temp.getBytes()); response.Data.Add(RealmData.RD_AUTH_SALT, salt); response.Data.Add(RealmData.RD_AUTH_N, N); return response; }
//*********************************************************************** // Probabilistic prime test based on Solovay-Strassen (Euler Criterion) // // p is probably prime if for any a < p (a is not multiple of p), // a^((p-1)/2) mod p = J(a, p) // // where J is the Jacobi symbol. // // Otherwise, p is composite. // // Returns // ------- // True if "this" is a Euler pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // //*********************************************************************** public bool SolovayStrassenTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); BigInteger p_sub1 = thisVal - 1; BigInteger p_sub1_shift = p_sub1 >> 1; Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; // calculate a^((p-1)/2) mod p BigInteger expResult = a.modPow(p_sub1_shift, thisVal); if(expResult == p_sub1) expResult = -1; // calculate Jacobi symbol BigInteger jacob = Jacobi(a, thisVal); //Console.WriteLine("a = " + a.ToString(10) + " b = " + thisVal.ToString(10)); //Console.WriteLine("expResult = " + expResult.ToString(10) + " Jacob = " + jacob.ToString(10)); // if they are different then it is not prime if(expResult != jacob) return false; } return true; }
private BigInteger[] genshares(BigInteger gp, BigInteger[] yrand) { int cnt = yrand.Length; BigInteger[] shares = new BigInteger[cnt]; for (int i = 0; i < cnt; i++) { shares[i] = gp.modPow(yrand[i], p); //Console.WriteLine("\nS-{0}: {1}", i, shares[i]); } return shares; }
//*********************************************************************** // Probabilistic prime test based on Fermat's little theorem // // for any a < p (p does not divide a) if // a^(p-1) mod p != 1 then p is not prime. // // Otherwise, p is probably prime (pseudoprime to the chosen base). // // Returns // ------- // True if "this" is a pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // // Note - this method is fast but fails for Carmichael numbers except // when the randomly chosen base is a factor of the number. // //*********************************************************************** public bool FermatLittleTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); BigInteger p_sub1 = thisVal - (new BigInteger(1)); Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; // calculate a^(p-1) mod p BigInteger expResult = a.modPow(p_sub1, thisVal); int resultLen = expResult.dataLength; // is NOT prime is a^(p-1) mod p != 1 if(resultLen > 1 || (resultLen == 1 && expResult.data[0] != 1)) { //Console.WriteLine("a = " + a.ToString()); return false; } } return true; }
private BigInteger RSADoPublic(BigInteger x) { return x.modPow(Exponent, Modulus); }
public DSAKeyPair(BigInteger p, BigInteger g, BigInteger q, BigInteger x) { BigInteger y = g.modPow(x, p); _publickey = new DSAPublicKey(p, g, q, y); _x = x; }
/** Commonly used BigInteger operations */ private static BigInteger modPower(BigInteger power_base, BigInteger exp, BigInteger mod) { return power_base.modPow(exp, mod); }
private static BigInteger findRandomGenerator(BigInteger order, BigInteger modulo, Random random) { BigInteger one = new BigInteger(1); BigInteger aux = modulo - new BigInteger(1); BigInteger t = aux % order; BigInteger generator; if(t.LongValue() != 0) { return null; } t = aux / order; while(true) { generator = new BigInteger(); generator.genRandomBits(modulo.bitCount(), random); generator = generator % modulo; generator = generator.modPow(t, modulo); if(generator!=one) break; } aux = generator.modPow(order, modulo); if(aux!=one) { return null; } return generator; }
private void _read_packets_loop() { _is_running = true; _client.Client.Blocking = true; _client.Client.ReceiveTimeout = -1; while (_is_running) { Thread.Sleep(10); if ((_client == null) || !_client.Connected) _is_running = false; byte[] buffer = new byte[4]; try { _client.Client.Receive(buffer); int size = (int)BitConverter.ToUInt16(buffer, 2); if (size == 0) continue; Array.Resize<byte>(ref buffer, buffer.Length + size); _client.Client.Receive(buffer,4,size,SocketFlags.None); } catch // Disconnected { break; } RealmPacket packet = RealmPacket.FromByteArray(buffer); switch (packet.opcode) { #region AUTH Packet case RealmOpcode.RS_AUTH_RECON_CHALLENGE: case RealmOpcode.RS_AUTH_LOGON_CHALLENGE: { RealmPacket response = new RealmPacket(); byte[] bytestosend; SHA1 sha = new SHA1CryptoServiceProvider(); byte[] user_pass = System.Text.Encoding.UTF8.GetBytes((("WoWMS:" + _password).ToCharArray())); byte[] hash = sha.ComputeHash(user_pass); byte[] salt = new byte[32]; new Random().NextBytes(salt); byte[] result = new byte[hash.Length + salt.Length]; hash.CopyTo(result, 0); salt.CopyTo(result, hash.Length); byte[] finalhash = sha.ComputeHash(result); byte[] rand = new byte[20]; new Random().NextBytes(rand); bR = (byte[])rand.Clone(); //BigInteger int_a = new BigInteger(reverse(finalhash)); //BigInteger int_b = new BigInteger(reverse(N)); BigInteger int_c = new BigInteger(new Byte[] { 7 }); BigInteger int_d = int_c.modPow(new BigInteger(reverse(finalhash)), new BigInteger(reverse(N))); BigInteger K = new BigInteger(new Byte[] { 3 }); BigInteger temp = ((K * int_d) + int_c.modPow(new BigInteger(reverse(rand)), new BigInteger(reverse(N)))) % new BigInteger(reverse(N)); this.bB = temp.getBytes(); response = new RealmPacket(); response.opcode = RealmOpcode.RS_AUTH_LOGON_CHALLENGE; response.Data.Add(RealmData.RD_AUTH_ERROR, 0); response.Data.Add(RealmData.RD_AUTH_HASH, temp.getBytes()); response.Data.Add(RealmData.RD_AUTH_SALT, salt); response.Data.Add(RealmData.RD_AUTH_N, N); //RealmPacket p = RealmPacket.CreateAuthResponse((string)packet.Data[RealmData.RD_ACCOUNT_NAME], _password); bytestosend = response.ToByteArray(); _client.Client.Send(bytestosend); break; } #endregion #region PROOF Packet case RealmOpcode.RS_AUTH_RECON_PROOF: case RealmOpcode.RS_AUTH_LOGON_PROOF: { RealmPacket response = new RealmPacket(); byte[] bytestosend; SHA1 sha = new SHA1CryptoServiceProvider(); response = new RealmPacket(); response.opcode = RealmOpcode.RS_AUTH_LOGON_PROOF; byte[] b = new byte[32 + bB.Length + 1 + 16 + 16]; BinaryWriter writer = new BinaryWriter(new MemoryStream(b)); //((byte[])packet.Data[RealmData.RD_SRP6_M1]).CopyTo(b, 0); writer.Write((byte[])packet.Data[RealmData.RD_SRP6_M1]); //bB.CopyTo(b, 32); writer.Write(bB); BigInteger u = new BigInteger(sha.ComputeHash(b)); BigInteger s = ((BigInteger)(new BigInteger((byte[])(packet.Data[RealmData.RD_SRP6_M1])) * (new BigInteger(bV).modPow(u, new BigInteger(N))))).modPow(new BigInteger(bR), new BigInteger(N)); byte[] t = s.getBytes(); byte[] t1 = new byte[16]; for (int i = 0; i < 16; i++) t1[i] = t[i * 2]; writer.Write(t1); byte[] hash = sha.ComputeHash(b); byte[] vK = new byte[40]; for (int i = 0; i < 20; i++) { vK[2 * i] = sha.ComputeHash(b)[i]; } for (int i = 0; i < 16; i++) t1[i] = t[i * 2 + 1]; writer.Write(t1); for (int i = 0; i < 20; i++) { vK[2 * i + 1] = sha.ComputeHash(b)[i]; } bytestosend = response.ToByteArray(); _client.Client.Send(bytestosend); break; } #endregion default: break; } } }
private BigInteger genQ(BigInteger x, BigInteger gp) { BigInteger Q = new BigInteger(gp.modPow(x, p)); //Console.WriteLine("\nQ: " + Q); return Q; }
//*********************************************************************** // Probabilistic prime test based on Rabin-Miller's // // for any p > 0 with p - 1 = 2^s * t // // p is probably prime (strong pseudoprime) if for any a < p, // 1) a^t mod p = 1 or // 2) a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 // // Otherwise, p is composite. // // Returns // ------- // True if "this" is a strong pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // //*********************************************************************** public bool RabinMillerTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; // calculate values of s and t BigInteger p_sub1 = thisVal - (new BigInteger(1)); int s = 0; for(int index = 0; index < p_sub1.dataLength; index++) { uint mask = 0x01; for(int i = 0; i < 32; i++) { if((p_sub1.data[index] & mask) != 0) { index = p_sub1.dataLength; // to break the outer loop break; } mask <<= 1; s++; } } BigInteger t = p_sub1 >> s; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; BigInteger b = a.modPow(t, thisVal); /* Console.WriteLine("a = " + a.ToString(10)); Console.WriteLine("b = " + b.ToString(10)); Console.WriteLine("t = " + t.ToString(10)); Console.WriteLine("s = " + s); */ bool result = false; if(b.dataLength == 1 && b.data[0] == 1) // a^t mod p = 1 result = true; for(int j = 0; result == false && j < s; j++) { if(b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 { result = true; break; } b = (b * b) % thisVal; } if(result == false) return false; } return true; }
public override byte[] ProcessDataReceived( byte []data, int length ) { // Console.WriteLine("Rec {0}", data[ 0 ] ); // HexViewer.View( data, 0, length ); int t; switch( data[ 0 ] ) { case 0x00:// Logon challenge /*foreach( Account acc in World.allAccounts ) if ( acc.Ip != null && ch.IP.Address == acc.Ip.Address && //ch.Port == acc.Port && (bool)tryLoggin[ ch.IP.Address.ToString() ] ) { Console.WriteLine("wait!!!"); return new byte[] { 0, 3, 0xEE, 0x1, 0x19 }; }*/ // Console.WriteLine( "Logon challenge" ); int clientVersion = ( ( (int)data[ 11 ] ) * 256 )+ data[ 12 ]; byte len = data[ 33 ]; userName = new byte[ len ]; //Console.Write( "User : "******""; for( t = 0;t < len;t++ ) { userName[ t ] = data[ 34 + t ]; usern+= "" + (char)data[ 34 + t ]; // Console.Write( "{0}", "" + ((char)userName[ t ] ).ToString() ); } // Console.WriteLine( "" ); myAccount = World.allAccounts.FindByUserName( usern ); if ( World.FreeForAll ) { if ( myAccount == null ) { World.allAccounts.Add( myAccount = new Account( usern, usern ) ); } } if ( myAccount == null ) return new byte[] { 0x1, 0x4 }; if ( myAccount.SelectedChar != null ) { // Console.WriteLine("Already loggin"); return new byte[] { 1, 0x6 }; // Already logged in } SHA1 sha = new SHA1CryptoServiceProvider(); string pass = "******" + myAccount.Password.ToUpper(); char []passc = pass.ToCharArray(); byte []passb = new byte[ passc.Length ]; int ti = 0; foreach( char c in passc ) passb[ ti++ ] = (byte)c; byte []user = Concat( userName, passb ); byte []hash = sha.ComputeHash( user, 0 , user.Length ); byte []res = new Byte[ hash.Length + salt.Length ]; t = 0; rand.NextBytes( salt ); foreach( byte s in salt ) res[ t++ ] = s; foreach( byte s in hash ) res[ t++ ] = s; byte []hash2 = sha.ComputeHash( res, 0, res.Length ); byte []x = Reverse( hash2 ); rN = Reverse( N ); rand.NextBytes( b ); rb = Reverse( b ); BigInteger bi = new BigInteger( x ); BigInteger bi2 = new BigInteger( rN ); BigInteger g = new BigInteger( new byte[] { 7 } ); v = g.modPow( bi, bi2 ); K = new BigInteger( new Byte[] { 3 } ); BigInteger temp1 = K * v; BigInteger temp2 = g.modPow( new BigInteger( rb ), new BigInteger( rN ) ); BigInteger temp3 = temp1 + temp2; B = temp3 % new BigInteger( rN ); /* byte []ezfd= B.getBytes(); Console.WriteLine("B"); HexViewer.View( ezfd, 0, ezfd.Length ); BigInteger C = new BigInteger(); Console.WriteLine("C/Rn {0}", temp3/new BigInteger( rN ) );*/ //Console.WriteLine("temp1 {0}",temp1.ToHexString()); //Console.WriteLine("temp2 {0}",temp2.ToHexString()); //Console.WriteLine("temp3 {0}",temp3.ToHexString()); /* for(int ll = 0;ll < 6;ll++) { C = B; C += new BigInteger( rN ) * ll; C -= temp1; Console.WriteLine("temp3 {0}",C.ToHexString()); }*/ byte []pack = new byte[ 118 ]; //byte[] pack = new byte[119]; pack[ 0 ] = pack[ 1 ] = 0; byte []tB = Reverse( B.getBytes() ); for( t = 0;t < tB.Length ;t++ ) pack[ 3 + t ] = tB[ t ]; pack[ 35 ] = 1;// g_length pack[ 36 ] = 7;// g pack[ 37 ] = 32;// n_len for( t = 0;t < N.Length;t++ ) pack[ 38 + t ] = N[ t ]; for( t = 0;t < salt.Length ;t++ ) pack[ 70 + t ] = salt[ t ]; for( t = 0;t < 16;t++ ) //for (t = 0; t < 17; t++) pack[ 102 + t ] = 0; return pack; case 0x01:// Logon proof { //Console.WriteLine("Logon proof" ); byte []A = new byte[ 32 ]; for( t = 0;t < 32;t++ ) { A[ t ] = data[ t + 1 ]; } byte []kM1 = new byte[ 20 ]; for( t = 0;t < 20;t++ ) { kM1[ t ] = data[ t + 1 + 32 ]; } //A = new byte[] { 0x23, 0x2f, 0xb1, 0xb8, 0x85, 0x29, 0x64, 0x3d, 0x95, 0xb8, 0xdc, 0xe7, 0x8f, 0x27, 0x50, 0xc7, 0x5b, 0x2d, 0xf3, 0x7a, 0xcb, 0xa8, 0x73, 0xeb, 0x31, 0x07, 0x38, 0x39, 0xed, 0xa0, 0x73, 0x8d }; byte []rA = Reverse( A ); // B = new BigInteger( new byte[] { 0x64, 0x5d, 0x1f, 0x78, 0x97, 0x30, 0x73, 0x70, 0x1e, 0x12, 0xbc, 0x98, 0xaa, 0x38, 0xea, 0x99, 0xb4, 0xbc, 0x43, 0x5c, 0x32, 0xe8, 0x44, 0x7c, 0x73, 0xab, 0x07, 0x7a, 0xe4, 0xd7, 0x59, 0x64 } ); byte []AB = Concat( A, Reverse( B.getBytes() ) ); SHA1 shaM1 = new SHA1CryptoServiceProvider(); byte []U = shaM1.ComputeHash( AB ); // U = new byte[] { 0x2f, 0x49, 0x69, 0xac, 0x9f, 0x38, 0x7f, 0xd6, 0x72, 0x23, 0x6f, 0x94, 0x91, 0xa5, 0x16, 0x77, 0x7c, 0xdd, 0xe1, 0xc1 }; byte []rU = Reverse( U ); temp1 = v.modPow( new BigInteger( rU ), new BigInteger( rN ) ); temp2 = temp1 * new BigInteger( rA ); temp3 = temp2.modPow( new BigInteger( rb ), new BigInteger( rN ) ); byte []S1 = new byte[ 16 ]; byte []S2 = new byte[ 16 ]; byte []S = new byte[ 32 ]; byte []temp = temp3.getBytes(); /* Console.WriteLine("temp"); HexViewer.View( temp, 0, temp.Length ); Console.WriteLine("temp1 {0}", temp1.ToHexString()); Console.WriteLine("temp2 {0}", temp2.ToHexString()); Console.WriteLine("temp3 {0}", temp3.ToHexString());*/ Buffer.BlockCopy( temp, 0, S, 0, temp.Length ); byte []rS = Reverse( S ); for( t = 0;t < 16;t++) { S1[ t ] = rS[ t * 2 ]; S2[ t ] = rS[ ( t * 2 ) + 1 ]; } byte []hashS1 = shaM1.ComputeHash( S1 ); byte []hashS2 = shaM1.ComputeHash( S2 ); myAccount.SS_Hash = new byte[ hashS1.Length + hashS2.Length ]; for( t = 0;t < hashS1.Length ;t++ ) { myAccount.SS_Hash[ t * 2 ] = hashS1[ t ]; myAccount.SS_Hash[ ( t * 2 ) + 1 ] = hashS2[ t ]; } // SS_Hash = new byte[] { 0x02, 0x61, 0xf4, 0xeb, 0x48, 0x91, 0xb6, 0x6a, 0x1a, 0x82, 0x6e, 0xb7, 0x79, 0x28, 0xd8, 0x64, 0xb7, 0xea, 0x14, 0x54, 0x38, 0xdb, 0x7c, 0xfd, 0x0d, 0x3d, 0x2f, 0xc0, 0x22, 0xce, 0xcc, 0x46, 0x83, 0x79, 0xf2, 0xc0, 0x87, 0x78, 0x7f, 0x14 }; byte []NHash = shaM1.ComputeHash( N ); byte []GHash = shaM1.ComputeHash( new byte[]{ 7 } ); byte []userHash = shaM1.ComputeHash( userName ); byte []NG_Hash = new byte[ 20 ]; for( t = 0;t < 20;t++ ) { NG_Hash[ t ] = (byte)( NHash[ t ] ^ GHash[ t ] ); } byte []Temp = Concat( NG_Hash, userHash ); Temp = Concat( Temp, salt ); Temp = Concat( Temp, A ); Temp = Concat( Temp, B.getBytes() ); Temp = Concat( Temp, K.getBytes() );//SS_Hash ); byte []M1 = shaM1.ComputeHash( Temp ); Temp = Concat( A, kM1 ); Temp = Concat( Temp, myAccount.SS_Hash ); byte []M2 = shaM1.ComputeHash( Temp ); byte []retur = new byte[ M2.Length + 4/*NG_Hash.Length */+ 2 ]; // byte []retur = new byte[ M2.Length + NG_Hash.Length + 2 ]; retur[ 0 ] = 0x1; retur[ 1 ] = 0x0; for(t = 0;t < M2.Length;t++ ) retur[ t + 2 ] = M2[ t ]; //for(t = 0;t < NG_Hash.Length;t++ ) // retur[ t + 2 + 20 ] = NG_Hash[ t ]; // set the account properties Console.WriteLine("Logon proof for {0},{1}", IP.ToString(), myAccount.Username ); myAccount.Ip = this.IP; myAccount.Port = 0; myAccount.K = myAccount.SS_Hash; return retur; } case 0x02:// Reconnect challenge { // Console.WriteLine( "Reconnect challenge" ); byte []packRecoChallenge = new byte[ 34 ]; packRecoChallenge[ 0 ] = 0x02; packRecoChallenge[ 1 ] = 0x00; for( t = 0;t < 16 ;t++ ) packRecoChallenge[ 18 + t ] = 0; return packRecoChallenge; } case 0x03:// Reconnect proof // Console.WriteLine( "Reconnect proof" ); return new byte[] { 0x03, 0x00 }; case 0x04:// Update server // Console.WriteLine( "Update server" ); break; case 0x10:// Realm List // Console.WriteLine( "Realm lList request" ); string ip = World.ServerIP; /* if ( base.theClientHandler.IP.ToString().StartsWith( "192.168.0" ) ) { ip = "192.168.0.2"; } else*/ if ( IP.ToString() == "127.0.0.1" ) { ip = "127.0.0.1"; } byte []retData = new byte[ 25 + ip.Length + World.ServerName.Length + World.ServerPort.ToString().Length ]; /* byte []retData = new byte[ ]{ 0x10, 45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, (byte)'D', (byte)'r', (byte)' ', (byte)'N', (byte)'e', (byte)'x', (byte)'u', (byte)'s', 0x00, (byte)'1', (byte)'9', (byte)'2', (byte)'.', (byte)'1', (byte)'6', (byte)'8', (byte)'.', (byte)'0', (byte)'.', (byte)'2', 0x3a, 0x38, 0x30, 0x38, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00 };*/ int offset = 0; Converter.ToBytes( (byte)0x10, retData, ref offset ); Converter.ToBytes( (byte)43, retData, ref offset ); Converter.ToBytes( 1/*World.allConnectedChars.Count*/, retData, ref offset ); Converter.ToBytes( (byte)0, retData, ref offset ); Converter.ToBytes( 1, retData, ref offset ); Converter.ToBytes( (short)0, retData, ref offset ); Converter.ToBytes( World.ServerName, retData, ref offset ); Converter.ToBytes( (byte)0, retData, ref offset ); Converter.ToBytes( ip, retData, ref offset ); Converter.ToBytes( (byte)':', retData, ref offset ); Converter.ToBytes( World.ServerPort.ToString(), retData, ref offset ); Converter.ToBytes( (byte)0, retData, ref offset ); Converter.ToBytes( 0, retData, ref offset ); // Converter.ToBytes( (short)0, retData, ref offset );// cr erreir //Converter.ToBytes( (short)1, retData, ref offset ); //Converter.ToBytes( (short)2, retData, ref offset ); Converter.ToBytes( (short)World.allConnectedChars.Count, retData, ref offset ); Converter.ToBytes( (byte)0, retData, ref offset ); Converter.ToBytes( (short)1, retData, ref offset ); int atlen = 1; offset -= 3; Converter.ToBytes( offset, retData, ref atlen ); Console.WriteLine("Connected player(s) {0}", World.allConnectedChars.Count ); /* if ( World.allConnectedChars.Count < 3 )*/ //Thread.Sleep( 500 ); return retData; default: Console.WriteLine( "Receive unknown command {0}", data[ 0 ] ); break; } byte []ret = { 0, 0, 0, 0 }; return ret; }
/// <summary> /// Decrypts Login Key from Client /// </summary> /// <param name="LoginKey">Login Key from Client</param> /// <param name="UserName">Username stored in Login Key</param> /// <param name="ServerSalt">Server Salt stored in Login Key</param> /// <param name="Password">Password stored in Login Key</param> public void DecryptLoginKey(string LoginKey, out string UserName, out string ServerSalt, out string Password) { string[] LoginKeySplit = LoginKey.Split('-'); BigInteger ClientPublicKey = new BigInteger(LoginKeySplit[0], 16); string EncryptedBlock = LoginKeySplit[1]; // These should really be in a config file, but for now hardcoded BigInteger ServerPrivateKey = new BigInteger("7ad852c6494f664e8df21446285ecd6f400cf20e1d872ee96136d7744887424b", 16); BigInteger Prime = new BigInteger( "eca2e8c85d863dcdc26a429a71a9815ad052f6139669dd659f98ae159d313d13c6bf2838e10a69b6478b64a24bd054ba8248e8fa778703b418408249440b2c1edd28853e240d8a7e49540b76d120d3b1ad2878b1b99490eb4a2a5e84caa8a91cecbdb1aa7c816e8be343246f80c637abc653b893fd91686cf8d32d6cfe5f2a6f", 16); string TeaKey = ClientPublicKey.modPow(ServerPrivateKey, Prime).ToString(16).ToLower(); if (TeaKey.Length < 32) // If TeaKey is not at least 128bits, pad to the left with 0x00 { TeaKey.PadLeft(32, '0'); } else // If TeaKey is more than 128bits, truncate { TeaKey = TeaKey.Substring(0, 32); } string DecryptedBlock = DecryptTea(EncryptedBlock, TeaKey); DecryptedBlock = DecryptedBlock.Substring(8); // Strip first 8 bytes of padding int DataLength = ConvertStringToIntSwapEndian(DecryptedBlock.Substring(0, 4)); DecryptedBlock = DecryptedBlock.Substring(4); string[] BlockParts = DecryptedBlock.Split(new[] {'|'}, 2); UserName = BlockParts[0]; ServerSalt = String.Empty; for (int i = 0; i < 32; i += 4) ServerSalt += String.Format("{0:x8}", ConvertStringToIntSwapEndian(BlockParts[1].Substring(i, 4))); Password = BlockParts[1].Substring(33, DataLength - 34 - UserName.Length); }