123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
- #pragma warning disable
- using System;
- using System.Diagnostics;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Generators;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
- using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
- namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Agreement
- {
- /**
- * a Diffie-Hellman key exchange engine.
- * <p>
- * note: This uses MTI/A0 key agreement in order to make the key agreement
- * secure against passive attacks. If you're doing Diffie-Hellman and both
- * parties have long term public keys you should look at using this. For
- * further information have a look at RFC 2631.</p>
- * <p>
- * It's possible to extend this to more than two parties as well, for the moment
- * that is left as an exercise for the reader.</p>
- */
- public class DHAgreement
- {
- private DHPrivateKeyParameters key;
- private DHParameters dhParams;
- private BigInteger privateValue;
- private SecureRandom random;
- public void Init(
- ICipherParameters parameters)
- {
- AsymmetricKeyParameter kParam;
- if (parameters is ParametersWithRandom)
- {
- ParametersWithRandom rParam = (ParametersWithRandom)parameters;
- this.random = rParam.Random;
- kParam = (AsymmetricKeyParameter)rParam.Parameters;
- }
- else
- {
- this.random = new SecureRandom();
- kParam = (AsymmetricKeyParameter)parameters;
- }
- if (!(kParam is DHPrivateKeyParameters))
- {
- throw new ArgumentException("DHEngine expects DHPrivateKeyParameters");
- }
- this.key = (DHPrivateKeyParameters)kParam;
- this.dhParams = key.Parameters;
- }
- /**
- * calculate our initial message.
- */
- public BigInteger CalculateMessage()
- {
- DHKeyPairGenerator dhGen = new DHKeyPairGenerator();
- dhGen.Init(new DHKeyGenerationParameters(random, dhParams));
- AsymmetricCipherKeyPair dhPair = dhGen.GenerateKeyPair();
- this.privateValue = ((DHPrivateKeyParameters)dhPair.Private).X;
- return ((DHPublicKeyParameters)dhPair.Public).Y;
- }
- /**
- * given a message from a given party and the corresponding public key
- * calculate the next message in the agreement sequence. In this case
- * this will represent the shared secret.
- */
- public BigInteger CalculateAgreement(
- DHPublicKeyParameters pub,
- BigInteger message)
- {
- if (pub == null)
- throw new ArgumentNullException("pub");
- if (message == null)
- throw new ArgumentNullException("message");
- if (!pub.Parameters.Equals(dhParams))
- throw new ArgumentException("Diffie-Hellman public key has wrong parameters.");
- BigInteger p = dhParams.P;
- BigInteger peerY = pub.Y;
- if (peerY == null || peerY.CompareTo(BigInteger.One) <= 0 || peerY.CompareTo(p.Subtract(BigInteger.One)) >= 0)
- throw new ArgumentException("Diffie-Hellman public key is weak");
- BigInteger result = peerY.ModPow(privateValue, p);
- if (result.Equals(BigInteger.One))
- throw new InvalidOperationException("Shared key can't be 1");
- return message.ModPow(key.X, p).Multiply(result).Mod(p);
- }
- }
- }
- #pragma warning restore
- #endif
|