public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < 1) { throw new ArgumentException("data"); } byte[] ecPointData = new byte[data[0]]; Buffer.BlockCopy(data, 1, ecPointData, 0, ecPointData.Length); ECPoint ecPoint = domainParameters.Curve.DecodePoint(ecPointData); var theirPublicKey = new ECPublicKeyParameters(ecPoint, domainParameters); // Calculate the actual agreement var agreement = new ECDHBasicAgreement(); agreement.Init(this.privateKey); var pmsLength = this.privateKey.Parameters.Curve.FieldSize / 8; preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), pmsLength); this.logger?.Debug("Pre-Master secret: " + BitConverter.ToString(preMasterSecret)); }
private (byte[], byte[]) ExtractDH(byte[] senderKey, byte[] receiverPrivateKey) { ECPoint pt = ecCurve.DecodePoint(senderKey); ECPublicKeyParameters publicKeyParams = new ECPublicKeyParameters(pt, ecDomainParameters); IBasicAgreement aKeyAgree = new ECDHBasicAgreement(); aKeyAgree.Init(privateKey); byte[] sharedSecret = aKeyAgree.CalculateAgreement(publicKeyParams).ToByteArrayUnsigned(); byte[] receiverKey = AddLengthPrefix(PublicKey); senderKey = AddLengthPrefix(senderKey); byte[] context = new byte[keyLabel.Length + 1 + receiverKey.Length + senderKey.Length]; int destinationOffset = 0; Array.Copy(keyLabel, 0, context, destinationOffset, keyLabel.Length); destinationOffset += keyLabel.Length + 1; Array.Copy(receiverKey, 0, context, destinationOffset, receiverKey.Length); destinationOffset += receiverKey.Length; Array.Copy(senderKey, 0, context, destinationOffset, senderKey.Length); return(sharedSecret, context); }
public void TestECDHBasicAgreementCofactor() { SecureRandom random = new SecureRandom(); X9ECParameters x9 = CustomNamedCurves.GetByName("curve25519"); ECDomainParameters ec = new ECDomainParameters(x9.Curve, x9.G, x9.N, x9.H, x9.GetSeed()); ECKeyPairGenerator kpg = new ECKeyPairGenerator(); kpg.Init(new ECKeyGenerationParameters(ec, random)); AsymmetricCipherKeyPair p1 = kpg.GenerateKeyPair(); AsymmetricCipherKeyPair p2 = kpg.GenerateKeyPair(); IBasicAgreement e1 = new ECDHBasicAgreement(); IBasicAgreement e2 = new ECDHBasicAgreement(); e1.Init(p1.Private); e2.Init(p2.Private); BigInteger k1 = e1.CalculateAgreement(p2.Public); BigInteger k2 = e2.CalculateAgreement(p1.Public); if (!k1.Equals(k2)) { Fail("calculated agreement test failed"); } }
/// <summary> /// Generates the KDF parameters. /// Sess Sections 7 & 8 of RFC 6637 (http://tools.ietf.org/html/rfc6637) for more details /// </summary> /// <returns></returns> private void UpdateDigestWithKDFParameters(IDigest digest) { var agreement = new ECDHBasicAgreement(); agreement.Init(_privateKey); var zb = agreement.CalculateAgreement(_publicKey).ToByteArrayUnsigned(); digest.Update(0x00); digest.Update(0x00); digest.Update(0x00); digest.Update(0x01); digest.BlockUpdate(zb, 0, zb.Length); var oid = _publicKey.PublicKeyParamSet.ToBytes(); digest.Update((byte)oid.Length); digest.BlockUpdate(oid, 0, oid.Length); digest.Update((byte)PublicKeyAlgorithmTag.Ecdh); digest.Update(0x3); digest.Update(0x1); digest.Update((byte)_publicKey.HashAlgorithm); digest.Update((byte)_publicKey.SymmetricKeyAlgorithm); digest.BlockUpdate(_anonymousSender, 0, _anonymousSender.Length); digest.BlockUpdate(_fingerPrint, 0, _fingerPrint.Length); }
public byte[] CalculateCommonSecret(EthECKey publicKey) { var agreement = new ECDHBasicAgreement(); agreement.Init(_ecKey.PrivateKey); var z = agreement.CalculateAgreement(publicKey._ecKey.GetPublicKeyParameters()); return BigIntegers.AsUnsignedByteArray(agreement.GetFieldSize(), z); }
public void TestECDHBasicAgreement() { SecureRandom random = new SecureRandom(); BigInteger n = new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307"); FpCurve curve = new FpCurve( new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16), // b n, BigInteger.One); ECDomainParameters parameters = new ECDomainParameters( curve, curve.DecodePoint(Hex.Decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G n, BigInteger.One); ECKeyPairGenerator pGen = new ECKeyPairGenerator(); ECKeyGenerationParameters genParam = new ECKeyGenerationParameters(parameters, random); pGen.Init(genParam); AsymmetricCipherKeyPair p1 = pGen.GenerateKeyPair(); AsymmetricCipherKeyPair p2 = pGen.GenerateKeyPair(); // // two way // IBasicAgreement e1 = new ECDHBasicAgreement(); IBasicAgreement e2 = new ECDHBasicAgreement(); e1.Init(p1.Private); e2.Init(p2.Private); BigInteger k1 = e1.CalculateAgreement(p2.Public); BigInteger k2 = e2.CalculateAgreement(p1.Public); if (!k1.Equals(k2)) { Fail("calculated agreement test failed"); } // // two way // e1 = new ECDHCBasicAgreement(); e2 = new ECDHCBasicAgreement(); e1.Init(p1.Private); e2.Init(p2.Private); k1 = e1.CalculateAgreement(p2.Public); k2 = e2.CalculateAgreement(p1.Public); if (!k1.Equals(k2)) { Fail("calculated agreement test failed"); } }
public static byte[] GetObsoleteSharedSecret(AsymmetricCipherKeyPair localKeyWithPrivate, byte[] remotePublicKeyDerEncoded) { var remotePublicKey = PublicKeyFactory.CreateKey(remotePublicKeyDerEncoded); var agreement = new ECDHBasicAgreement(); agreement.Init(localKeyWithPrivate.Private); return(agreement.CalculateAgreement(remotePublicKey).ToByteArray()); }
public static byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { ECDHBasicAgreement eCDHBasicAgreement = new ECDHBasicAgreement(); eCDHBasicAgreement.Init(privateKey); BigInteger n = eCDHBasicAgreement.CalculateAgreement(publicKey); return(BigIntegers.AsUnsignedByteArray(eCDHBasicAgreement.GetFieldSize(), n)); }
protected virtual byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); basicAgreement.Init(privateKey); BigInteger agreement = basicAgreement.CalculateAgreement(publicKey); return(BigIntegers.AsUnsignedByteArray(agreement)); }
static byte[] EcdhKeyAgreementZ(ECPublicKeyParameters externalPublicKey, ECPrivateKeyParameters ephemeralPrvKey) { var ecdh = new ECDHBasicAgreement(); ecdh.Init(ephemeralPrvKey); var z = ecdh.CalculateAgreement(externalPublicKey); return(BigIntegers.AsUnsignedByteArray(z)); }
/// <summary> /// Creates symmetric key from sender's public key and own key pair /// </summary> /// <param name="publicKeyBytes"></param> /// <returns></returns> protected byte[] GetSymmetricKey(byte[] publicKeyBytes) { ECPublicKeyParameters publicKey = new ECPublicKeyParameters(X9.Curve.DecodePoint(publicKeyBytes), EcSpec); var agree = new ECDHBasicAgreement(); agree.Init(KeyPair.Private); BigInteger z = agree.CalculateAgreement((AsymmetricKeyParameter)publicKey); return(BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z)); }
/// <summary> /// Derives a shared secret key from a private key and another persons public key /// </summary> /// <param name="myPrivateKey">the private key which is used</param> /// <param name="otherPartyPublicKey">the public key of the other person</param> /// <returns></returns> public byte[] DeriveKey(byte[] myPrivateKey, byte[] otherPartyPublicKey) { ECPrivateKeyParameters privKey = null; try { privKey = (ECPrivateKeyParameters)CreateAsymmetricKeyParameterFromPrivateKeyInfo(myPrivateKey); } catch (InvalidCastException exception) { string message = "Private Key Import Failed!\n" + $"{exception.Message}.\n" + "The contents of the source do not represent a valid EC key parameter\n" + "Verify that the key is not corrupted.\n" + "- or - Verify that the correct key is selected."; throw new CryptoException(message, exception); } var a1 = new ECDHBasicAgreement(); a1.Init(privKey); ECPublicKeyParameters pubKey = null; try { pubKey = (ECPublicKeyParameters)CreateAsymmetricKeyParameterFromPublicKeyInfo(otherPartyPublicKey); } catch (InvalidCastException exception) { string message = "Public Key Import Failed!\n" + $"{exception.Message}.\n" + "The contents of the source do not represent a valid EC key parameter\n" + "Verify that the key is not corrupted.\n" + "- or - Verify that the correct key is selected."; throw new CryptoException(message, exception); } BigInteger k = null; try { k = a1.CalculateAgreement(pubKey); } catch (InvalidOperationException exception) { string message = "Key Deriviation Failed!\n" + $"{exception.Message}.\n" + "Different EC curves were used to create the public keys."; throw new CryptoException(message, exception); } return(k.ToByteArrayUnsigned()); }
public static byte[] GetSharedSecret(AsymmetricCipherKeyPair localKeyWithPrivate, byte[] remotePublicKeyDerEncoded) { var remotePublicKey = PublicKeyFactory.CreateKey(remotePublicKeyDerEncoded); var agreement = new ECDHBasicAgreement(); agreement.Init(localKeyWithPrivate.Private); using (var sha = SHA256.Create()) { // CalculateAgreement returns a BigInteger, whose length is variable, and bits are not whitened. // So hash it. return(sha.ComputeHash(agreement.CalculateAgreement(remotePublicKey).ToByteArray())); } }
public static byte[] Agree(PrivateKey privateKey, PublicKey publicKey) { ECPrivateKeyParameters privateKeyParameters = WrapPrivateKey(privateKey); ECPublicKeyParameters publicKeyParameters = WrapPublicKey(publicKey); ECDHBasicAgreement agreement = new ECDHBasicAgreement(); agreement.Init(privateKeyParameters); byte[] agreementBytes = agreement.CalculateAgreement(publicKeyParameters).ToByteArray(); return(agreementBytes.Length > 32 ? agreementBytes.Slice(agreementBytes.Length - 32, 32) : agreementBytes.PadLeft(32)); }
public string GenerateSharedSecretHex(string pubKeyHex) { var pubKeyBytes = pubKeyHex.HexToByteArray(); var q = _curve.Curve.DecodePoint(pubKeyBytes); var remotePublicKey = new ECPublicKeyParameters("ECDH", q, _domain); var agreement = new ECDHBasicAgreement(); agreement.Init(_key.Private); var basicAgreementResult = agreement.CalculateAgreement(remotePublicKey); return(BigIntegers.AsUnsignedByteArray(agreement.GetFieldSize(), basicAgreementResult).ToHex(true)); }
public byte[] Old() { ECPrivateKeyParameters privateKeyParameters = BouncyCrypto.WrapPrivateKey(privateKey); ECPublicKeyParameters publicKeyParameters = BouncyCrypto.WrapPublicKey(ephemeral); IBasicAgreement agreement = new ECDHBasicAgreement(); agreement.Init(privateKeyParameters); BigInteger zAsInteger = agreement.CalculateAgreement(publicKeyParameters); byte[] bytes = BigIntegers.AsUnsignedByteArray(32, zAsInteger); return(bytes); }
BigInteger ECDHAgree(byte[] publicKey, byte[] privateKey) { var domain = SecNamedCurves.GetByName("secp160r1"); ECDHBasicAgreement agreement = new ECDHBasicAgreement(); BigInteger privKeyInt = new BigInteger(privateKey); ECDomainParameters parm = new ECDomainParameters(domain.Curve, domain.G, domain.N); ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(privKeyInt, parm); agreement.Init(privKey); var pt = Key.Curve.Curve.DecodePoint(publicKey); ECPublicKeyParameters pubParams = new ECPublicKeyParameters(pt, parm); return(agreement.CalculateAgreement(pubParams)); }
public static byte[] CalculateECDHBasicAgreement(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { ECDHBasicAgreement basicAgreement = new ECDHBasicAgreement(); basicAgreement.Init(privateKey); BigInteger agreementValue = basicAgreement.CalculateAgreement(publicKey); /* * RFC 4492 5.10. Note that this octet string (Z in IEEE 1363 terminology) as output by * FE2OSP, the Field Element to Octet String Conversion Primitive, has constant length for * any given field; leading zeros found in this octet string MUST NOT be truncated. */ return(BigIntegers.AsUnsignedByteArray(basicAgreement.GetFieldSize(), agreementValue)); }
public string GenerateSharedSecretHex(string pubKeyHex) { var encoded = pubKeyHex.HexToByteArray(); if (encoded.Length == 64) { var numArray = new byte[encoded.Length + 1]; numArray[0] = (byte)4; Array.Copy((Array)encoded, 0, (Array)numArray, 1, encoded.Length); encoded = numArray; } var publicKeyParameters = new ECPublicKeyParameters("ECDH", ECDH_Key._curve.Curve.DecodePoint(encoded), ECDH_Key._domain); var ecdhBasicAgreement = new ECDHBasicAgreement(); ecdhBasicAgreement.Init(_key.Private); return(BigIntegers.AsUnsignedByteArray(ecdhBasicAgreement.GetFieldSize(), ecdhBasicAgreement.CalculateAgreement((ICipherParameters)publicKeyParameters)).ToHex(true)); }
internal static byte[] ComputeSharedSecret(ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) { if (!KeyParser.ValidateCurve(privateKey)) { throw new ArgumentException("Private key not on NIST P-256 curve", "privateKey"); } if (!KeyParser.ValidateCurve(publicKey)) { throw new ArgumentException("Public key not on NIST P-256 curve", "publicKey"); } var ecdhAgreement = new ECDHBasicAgreement(); ecdhAgreement.Init(privateKey); BigInteger secret = ecdhAgreement.CalculateAgreement(publicKey); return(BigIntegers.AsUnsignedByteArray(SharedSecretSize, secret)); }
/// <summary> /// Called by client to get his ephemaral ECC keys /// TODO: get information about which ECC curve should be used /// </summary> /// <param name="version"></param> /// <param name="data"></param> /// <returns></returns> public override byte[] ProcessServerKeys(ProtocolVersion version, byte[] data, X509Certificate serverCertificate) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (data.Length < 4) { throw new ArgumentException(nameof(data)); } //if (data[0] != 3 || data[1] != 0 || data[2] != 23) if (data[0] != 3 || data[1] != 0) { throw new ArgumentException(nameof(data)); } //if (data[3] != 65 || data[4] > data.Length - 4) if (data[4] > data.Length - 4) { throw new ArgumentException(nameof(data)); } // Extract the public key from the data byte[] ecPointData = new byte[data[3]]; Buffer.BlockCopy(data, 4, ecPointData, 0, ecPointData.Length); ushort curveNameId = (ushort)(data[1] << 8 | data[2]); var ecPoint = this.ObtainCurveNameAndPoint(curveNameId, ecPointData); var theirPublicKey = new ECPublicKeyParameters(ecPoint, this.domainParameters); // Calculate the actual agreement var agreement = new ECDHBasicAgreement(); agreement.Init(this.privateKey); this.preMasterSecret = BigIntegerToByteArray(agreement.CalculateAgreement(theirPublicKey), ecPoint.Curve.FieldSize / 8); var signature = new byte[data.Length - 4 - data[3]]; Buffer.BlockCopy(data, 4 + data[3], signature, 0, signature.Length); return(signature); }
public static byte[] AsymmetricDecrypt(byte[] data, ref AsymmetricCipherKeyPair keypair) { //create the key agreement ECDHBasicAgreement ag = new ECDHBasicAgreement(); ag.Init(keypair.Private); //calculate the shared secret key BigInteger a = ag.CalculateAgreement(keypair.Public); byte[] secret = a.ToByteArray(); //derive the symmetric encryption key ECDHKekGenerator topkek = new ECDHKekGenerator(DigestUtilities.GetDigest("SHA256")); topkek.Init(new DHKdfParameters(NistObjectIdentifiers.Aes, secret.Length, secret)); byte[] symKey = new byte[DigestUtilities.GetDigest("SHA256").GetDigestSize()]; topkek.GenerateBytes(symKey, 0, symKey.Length); //decrypt the data KeyParameter parm = ParameterUtilities.CreateKeyParameter("DES", symKey); IBufferedCipher cipher = CipherUtilities.GetCipher("DES/ECB/ISO7816_4PADDING"); cipher.Init(false, parm); byte[] ret = null; try { ret = cipher.DoFinal(data); } catch (Exception e) { if (e != null) { return(null); } } //erase the keys Eraser.SecureErase(secret); Eraser.SecureErase(symKey); return(ret); }
static byte[] GenerateAESKey(ECPublicKeyParameters bobPublicKey, AsymmetricKeyParameter alicePrivateKey) { ECDHBasicAgreement aKeyAgree = new ECDHBasicAgreement(); aKeyAgree.Init(alicePrivateKey); byte[] sharedSecret = aKeyAgree.CalculateAgreement(bobPublicKey).ToByteArray(); // make sure each part has the correct and same size ResizeRight(ref sharedSecret, 66); // 66 is the desired key size Sha256Digest digest = new Sha256Digest(); byte[] symmetricKey = new byte[digest.GetDigestSize()]; digest.BlockUpdate(sharedSecret, 0, sharedSecret.Length); digest.DoFinal(symmetricKey, 0); return(symmetricKey); }
public static byte[] GenerateSharedSecret(ECPublicKeyParameters publicKey, ECPrivateKeyParameters privateKey) { var agreement = new ECDHBasicAgreement(); agreement.Init(privateKey); var z = agreement.CalculateAgreement(publicKey); var sharedSecret = new byte[32]; var zArr = z.ToByteArrayUnsigned(); // zero the output array for (var i = 0; i < sharedSecret.Length; i++) { sharedSecret[i] = 0; } Array.Copy(zArr, 0, sharedSecret, 32 - zArr.Length, zArr.Length); return(sharedSecret); }
public static EncryptionResult EncryptMessage(byte[] userKey, byte[] userSecret, byte[] data, ushort padding = 0, bool randomisePadding = false) { var Random = new SecureRandom(); var Salt = new byte[16]; Random.NextBytes(Salt); var Curve = ECNamedCurveTable.GetByName("prime256v1"); var Spec = new ECDomainParameters(Curve.Curve, Curve.G, Curve.N, Curve.H, Curve.GetSeed()); var Generator = new ECKeyPairGenerator(); Generator.Init(new ECKeyGenerationParameters(Spec, new SecureRandom())); var KeyPair = Generator.GenerateKeyPair(); var AgreementGenerator = new ECDHBasicAgreement(); AgreementGenerator.Init(KeyPair.Private); var IKM = AgreementGenerator.CalculateAgreement(new ECPublicKeyParameters(Spec.Curve.DecodePoint(userKey), Spec)); var PRK = GenerateHKDF(userSecret, IKM.ToByteArrayUnsigned(), Encoding.UTF8.GetBytes("Content-Encoding: auth\0"), 32); var PublicKey = ((ECPublicKeyParameters)KeyPair.Public).Q.GetEncoded(false); var CEK = GenerateHKDF(Salt, PRK, CreateInfoChunk("aesgcm", userKey, PublicKey), 16); var Nonce = GenerateHKDF(Salt, PRK, CreateInfoChunk("nonce", userKey, PublicKey), 12); if (randomisePadding && padding > 0) { padding = Convert.ToUInt16(Math.Abs(Random.NextInt()) % (padding + 1)); } var Input = new byte[padding + 2 + data.Length]; Buffer.BlockCopy(ConvertInt(padding), 0, Input, 0, 2); Buffer.BlockCopy(data, 0, Input, padding + 2, data.Length); var Cipher = CipherUtilities.GetCipher("AES/GCM/NoPadding"); Cipher.Init(true, new AeadParameters(new KeyParameter(CEK), 128, Nonce)); var Message = new byte[Cipher.GetOutputSize(Input.Length)]; Cipher.DoFinal(Input, 0, Input.Length, Message, 0); return(new EncryptionResult { Salt = Salt, Payload = Message, PublicKey = PublicKey }); }
public static byte[] GetSharedSecret(byte[] localPrivateKeyBytes, byte[] remotePublicKeyBytes) { var curve = NistNamedCurves.GetByName("P-256"); var dom = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H); ECKeyParameters privateKeyParameters = new ECPrivateKeyParameters(new BigInteger(1, localPrivateKeyBytes), dom); var q = curve.Curve.DecodePoint(new byte[] { 0x04 }.Concat(remotePublicKeyBytes).ToArray()); ECKeyParameters publicKeyParameters = new ECPublicKeyParameters(q, dom); var agreement = new ECDHBasicAgreement(); agreement.Init(privateKeyParameters); using (var sha = SHA256.Create()) { // CalculateAgreement returns a BigInteger, whose length is variable, and bits are not whitened, so hash it. var temp = agreement.CalculateAgreement(publicKeyParameters).ToByteArray(); return(sha.ComputeHash(temp)); } }
public virtual Task <byte[]> SharedSecret(ECDSAPublicKey Pbk) { return(Task.Run(() => { lock (Cache) { var clipped = Pbk.FingerprintEncodedClipped; if (Cache.ContainsKey(clipped)) { return Cache[clipped]; } } var agree = new ECDHBasicAgreement(); agree.Init(PrivateKey); var result = agree.CalculateAgreement(Pbk.PublicKey).ToByteArrayUnsigned(); result = CryptoHelper.Sha256(result); lock (Cache) Cache[Pbk.FingerprintEncodedClipped] = result; return result; })); }
private PascalCoinIesEngine GetEciesPascalCoinCompatibilityEngine() { // Set up IES Cipher Engine For Compatibility With PascalCoin ECDHBasicAgreement ecdhBasicAgreementInstance = new ECDHBasicAgreement(); PascalCoinEciesKdfBytesGenerator kdfInstance = new PascalCoinEciesKdfBytesGenerator (DigestUtilities.GetDigest("SHA-512")); IMac digestMacInstance = MacUtilities.GetMac("HMAC-MD5"); // Set Up Block Cipher AesEngine aesEngine = new AesEngine(); // AES Engine BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(aesEngine), new ZeroBytePadding()); // AES-256 CBC ZeroBytePadding return(new PascalCoinIesEngine(ecdhBasicAgreementInstance, kdfInstance, digestMacInstance, cipher)); }
private static EncryptionResult EncryptMessage(byte[] userKey, byte[] userSecret, byte[] data, ushort padding = 0, bool randomisePadding = false) { SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; random.NextBytes(salt); X9ECParameters curve = ECNamedCurveTable.GetByName("prime256v1"); ECDomainParameters spec = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed()); ECKeyPairGenerator generator = new ECKeyPairGenerator(); generator.Init(new ECKeyGenerationParameters(spec, new SecureRandom())); AsymmetricCipherKeyPair keyPair = generator.GenerateKeyPair(); ECDHBasicAgreement agreementGenerator = new ECDHBasicAgreement(); agreementGenerator.Init(keyPair.Private); BigInteger ikm = agreementGenerator.CalculateAgreement(new ECPublicKeyParameters(spec.Curve.DecodePoint(userKey), spec)); byte[] prk = GenerateHkdf(userSecret, ikm.ToByteArrayUnsigned(), Encoding.UTF8.GetBytes("Content-Encoding: auth\0"), 32); byte[] publicKey = ((ECPublicKeyParameters)keyPair.Public).Q.GetEncoded(false); byte[] cek = GenerateHkdf(salt, prk, CreateInfoChunk("aesgcm", userKey, publicKey), 16); byte[] nonce = GenerateHkdf(salt, prk, CreateInfoChunk("nonce", userKey, publicKey), 12); if (randomisePadding && padding > 0) { padding = Convert.ToUInt16(Math.Abs(random.NextInt()) % (padding + 1)); } byte[] input = new byte[padding + 2 + data.Length]; Buffer.BlockCopy(ConvertInt(padding), 0, input, 0, 2); Buffer.BlockCopy(data, 0, input, padding + 2, data.Length); IBufferedCipher cipher = CipherUtilities.GetCipher("AES/GCM/NoPadding"); cipher.Init(true, new AeadParameters(new KeyParameter(cek), 128, nonce)); byte[] message = new byte[cipher.GetOutputSize(input.Length)]; cipher.DoFinal(input, 0, input.Length, message, 0); return(new EncryptionResult() { Salt = salt, Payload = message, PublicKey = publicKey }); }
public new void InitiateEncryption(byte[] serverKey, byte[] randomKeyToken) { try { ECPublicKeyParameters remotePublicKey = (ECPublicKeyParameters) PublicKeyFactory.CreateKey(serverKey); ECDHBasicAgreement agreement = new ECDHBasicAgreement(); agreement.Init(Session.CryptoContext.ClientKey.Private); byte[] secret; using (var sha = SHA256.Create()) { secret = sha.ComputeHash(randomKeyToken.Concat(agreement.CalculateAgreement(remotePublicKey).ToByteArrayUnsigned()).ToArray()); } // Create a decrytor to perform the stream transform. IBufferedCipher decryptor = CipherUtilities.GetCipher("AES/CFB8/NoPadding"); decryptor.Init(false, new ParametersWithIV(new KeyParameter(secret), secret.Take(16).ToArray())); IBufferedCipher encryptor = CipherUtilities.GetCipher("AES/CFB8/NoPadding"); encryptor.Init(true, new ParametersWithIV(new KeyParameter(secret), secret.Take(16).ToArray())); Session.CryptoContext = new CryptoContext { Decryptor = decryptor, Encryptor = encryptor, UseEncryption = true, Key = secret }; Thread.Sleep(1250); McpeClientToServerHandshake magic = new McpeClientToServerHandshake(); SendPacket(magic); } catch (Exception e) { Log.Error("Initiate encryption", e); } }