public byte[] EncryptSessionInfo(ReadOnlySpan <byte> sessionInfo) { var publicKeyParams = ecdh.PublicKey.ExportParameters(); // Generate the ephemeral key pair var ephemeralEcDh = CreateECDiffieHellman(publicKeyParams.Curve); var derivedKey = ephemeralEcDh.DeriveKeyFromHash( ecdh.PublicKey, PgpUtilities.GetHashAlgorithmName(this.hashAlgorithm), new byte[] { 0, 0, 0, 1 }, CreateUserKeyingMaterial(publicKeyParams.Curve.Oid)); derivedKey = derivedKey.AsSpan(0, PgpUtilities.GetKeySize(symmetricAlgorithm) / 8).ToArray(); byte[] paddedSessionData = PadSessionData(sessionInfo); byte[] C = SymmetricKeyWrap.AESKeyWrapEncrypt(derivedKey, paddedSessionData); var ep = ephemeralEcDh.PublicKey.ExportParameters(); byte[] VB = EncodePoint(ep.Q, publicKeyParams.Curve.Oid); byte[] rv = new byte[VB.Length + 2 + 1 + C.Length]; MPInteger.TryWriteInteger(VB, rv, out _); //Array.Copy(VB, 0, rv, 0, VB.Length); rv[VB.Length + 2] = (byte)C.Length; Array.Copy(C, 0, rv, VB.Length + 3, C.Length); return(rv); }
public bool TryDecryptSessionInfo(ReadOnlySpan <byte> encryptedSessionData, Span <byte> sessionData, out int bytesWritten) { var pEnc = MPInteger.ReadInteger(encryptedSessionData, out int pointBytesRead); encryptedSessionData = encryptedSessionData.Slice(pointBytesRead); int keyLen = encryptedSessionData[0]; var keyEnc = encryptedSessionData.Slice(1, keyLen); var publicParams = ecdh.PublicKey.ExportParameters(); var publicPoint = DecodePoint(pEnc); var otherEcdh = CreateECDiffieHellman(new ECParameters { Curve = publicParams.Curve, Q = publicPoint }); var derivedKey = ecdh.DeriveKeyFromHash( otherEcdh.PublicKey, PgpUtilities.GetHashAlgorithmName(this.hashAlgorithm), new byte[] { 0, 0, 0, 1 }, CreateUserKeyingMaterial(publicParams.Curve.Oid)); derivedKey = derivedKey.AsSpan(0, PgpUtilities.GetKeySize(this.symmetricAlgorithm) / 8).ToArray(); var C = SymmetricKeyWrap.AESKeyWrapDecrypt(derivedKey, keyEnc.ToArray()); var data = UnpadSessionData(C); if (sessionData.Length >= data.Length) { data.CopyTo(sessionData); bytesWritten = data.Length; return(true); } bytesWritten = 0; return(false); }