private byte[] EncryptSessionInfo(byte[] sessionInfo, SecureRandom random) { if (pubKey.Algorithm != PublicKeyAlgorithmTag.ECDH) { IBufferedCipher c; switch (pubKey.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaGeneral: c = CipherUtilities.GetCipher("RSA//PKCS1Padding"); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: c = CipherUtilities.GetCipher("ElGamal/ECB/PKCS1Padding"); break; case PublicKeyAlgorithmTag.Dsa: throw new PgpException("Can't use DSA for encryption."); case PublicKeyAlgorithmTag.ECDsa: throw new PgpException("Can't use ECDSA for encryption."); default: throw new PgpException("unknown asymmetric algorithm: " + pubKey.Algorithm); } AsymmetricKeyParameter akp = pubKey.GetKey(); c.Init(true, new ParametersWithRandom(akp, random)); return(c.DoFinal(sessionInfo)); } ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKey.PublicKeyPacket.Key; // Generate the ephemeral key pair IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH"); gen.Init(new ECKeyGenerationParameters(ecKey.CurveOid, random)); AsymmetricCipherKeyPair ephKp = gen.GenerateKeyPair(); ECPrivateKeyParameters ephPriv = (ECPrivateKeyParameters)ephKp.Private; ECPublicKeyParameters ephPub = (ECPublicKeyParameters)ephKp.Public; ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey.GetKey(); ECPoint S = pub.Q.Multiply(ephPriv.D).Normalize(); KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, S)); IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); w.Init(true, new ParametersWithRandom(key, random)); byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo); byte[] C = w.Wrap(paddedSessionData, 0, paddedSessionData.Length); byte[] VB = new MPInteger(new BigInteger(1, ephPub.Q.GetEncoded(false))).GetEncoded(); byte[] rv = new byte[VB.Length + 1 + C.Length]; Array.Copy(VB, 0, rv, 0, VB.Length); rv[VB.Length] = (byte)C.Length; Array.Copy(C, 0, rv, VB.Length + 1, C.Length); return(rv); }
private byte[] RecoverSessionData(PgpPrivateKey privKey) { byte[][] secKeyData = keyData.GetEncSessionKey(); if (keyData.Algorithm == PublicKeyAlgorithmTag.ECDH) { ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)privKey.PublicKeyPacket.Key; X9ECParameters x9Params = ECKeyPairGenerator.FindECCurveByOid(ecKey.CurveOid); byte[] enc = secKeyData[0]; int pLen = ((((enc[0] & 0xff) << 8) + (enc[1] & 0xff)) + 7) / 8; byte[] pEnc = new byte[pLen]; Array.Copy(enc, 2, pEnc, 0, pLen); byte[] keyEnc = new byte[enc[pLen + 2]]; Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length); ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc); ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key; ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize(); KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S)); IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm); w.Init(false, key); return(PgpPad.UnpadSessionData(w.Unwrap(keyEnc, 0, keyEnc.Length))); } IBufferedCipher cipher = GetKeyCipher(keyData.Algorithm); try { cipher.Init(false, privKey.Key); } catch (InvalidKeyException e) { throw new PgpException("error setting asymmetric cipher", e); } if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral) { byte[] bi = secKeyData[0]; cipher.ProcessBytes(bi, 2, bi.Length - 2); } else { ElGamalPrivateKeyParameters k = (ElGamalPrivateKeyParameters)privKey.Key; int size = (k.Parameters.P.BitLength + 7) / 8; ProcessEncodedMpi(cipher, size, secKeyData[0]); ProcessEncodedMpi(cipher, size, secKeyData[1]); } try { return(cipher.DoFinal()); } catch (Exception e) { throw new PgpException("exception decrypting secret key", e); } }