1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- using System;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Linq;
- using System.Numerics;
- using System.Security.Cryptography;
- namespace FxSsh.Algorithms
- {
- public class DiffieHellman : AsymmetricAlgorithm
- {
- // http://tools.ietf.org/html/rfc2412
- private const string Okley1024 = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF";
- // http://tools.ietf.org/html/rfc3526
- private const string Okley2048 = "00FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
- private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
- private BigInteger _p;
- private BigInteger _g;
- private BigInteger _x;
- public DiffieHellman(int bitlen)
- {
- Contract.Requires(bitlen == 1024 || bitlen == 2048);
- if (bitlen == 1024)
- {
- _p = BigInteger.Parse(Okley1024, NumberStyles.HexNumber);
- _g = new BigInteger(2);
- }
- else if (bitlen == 2048)
- {
- _p = BigInteger.Parse(Okley2048, NumberStyles.HexNumber);
- _g = new BigInteger(2);
- }
- else
- throw new ArgumentException("bitlen", "bitlen must equal 1024 or 2048");
- var bytes = new byte[80]; // 80 * 8 = 640 bits
- _rng.GetBytes(bytes);
- _x = BigInteger.Abs(new BigInteger(bytes));
- }
- public byte[] CreateKeyExchange()
- {
- var y = BigInteger.ModPow(_g, _x, _p);
- var bytes = BigintToBytes(y);
- return bytes;
- }
- public byte[] DecryptKeyExchange(byte[] keyEx)
- {
- Contract.Requires(keyEx != null);
- var pvr = BytesToBigint(keyEx);
- var z = BigInteger.ModPow(pvr, _x, _p);
- var bytes = BigintToBytes(z);
- return bytes;
- }
- private BigInteger BytesToBigint(byte[] bytes)
- {
- return new BigInteger(bytes.Reverse().Concat(new byte[] { 0 }).ToArray());
- }
- private byte[] BigintToBytes(BigInteger bigint)
- {
- var bytes = bigint.ToByteArray();
- if (bytes.Length > 1 && bytes[bytes.Length - 1] == 0)
- {
- return bytes.Reverse().Skip(1).ToArray();
- }
- return bytes.Reverse().ToArray();
- }
- }
- }
|