/// <summary> /// Extract a <c>PgpPrivateKey</c> from this secret key's encrypted contents. /// </summary> /// <param name="passPhrase"></param> /// <returns></returns> /// <exception cref="PgpException"> /// unknown public key algorithm encountered /// or /// Exception constructing key /// </exception> public IPgpPrivateKey ExtractPrivateKey(char[] passPhrase) { var secKeyData = _secret.GetSecretKeyData(); if (secKeyData == null || secKeyData.Length < 1) { return(null); } var pubPk = _secret.PublicKeyPacket; try { var data = ExtractKeyData(passPhrase); using (var memory = new MemoryStream(data, false)) { using (var bcpgIn = BcpgInputStream.Wrap(memory)) { IAsymmetricKeyParameter privateKey; switch (pubPk.Algorithm) { case PublicKeyAlgorithmTag.RsaEncrypt: case PublicKeyAlgorithmTag.RsaGeneral: case PublicKeyAlgorithmTag.RsaSign: var rsaPub = (RsaPublicBcpgKey)pubPk.Key; var rsaPriv = new RsaSecretBcpgKey(bcpgIn); var rsaPrivSpec = new RsaPrivateCrtKeyParameters( rsaPriv.Modulus, rsaPub.PublicExponent, rsaPriv.PrivateExponent, rsaPriv.PrimeP, rsaPriv.PrimeQ, rsaPriv.PrimeExponentP, rsaPriv.PrimeExponentQ, rsaPriv.CrtCoefficient); privateKey = rsaPrivSpec; break; case PublicKeyAlgorithmTag.Dsa: var dsaPub = (DsaPublicBcpgKey)pubPk.Key; var dsaPriv = new DsaSecretBcpgKey(bcpgIn); var dsaParams = new DsaParameters(dsaPub.P, dsaPub.Q, dsaPub.G); privateKey = new DsaPrivateKeyParameters(dsaPriv.X, dsaParams); break; case PublicKeyAlgorithmTag.ElGamalEncrypt: case PublicKeyAlgorithmTag.ElGamalGeneral: var elPub = (ElGamalPublicBcpgKey)pubPk.Key; var elPriv = new ElGamalSecretBcpgKey(bcpgIn); var elParams = new ElGamalParameters(elPub.P, elPub.G); privateKey = new ElGamalPrivateKeyParameters(elPriv.X, elParams); break; case PublicKeyAlgorithmTag.Ecdh: var ecdhPub = (ECDHPublicBcpgKey)pubPk.Key; var ecdhPriv = new ECSecretBcpgKey(bcpgIn); privateKey = new ECDHPrivateKeyParameters(ecdhPriv.X, new ECDHPublicKeyParameters(ecdhPub.Point, ecdhPub.Oid, ecdhPub.HashAlgorithm, ecdhPub.SymmetricKeyAlgorithm), PgpPublicKey.BuildFingerprint(pubPk)); break; case PublicKeyAlgorithmTag.Ecdsa: var ecdsaPub = (ECPublicBcpgKey)pubPk.Key; var ecdsaPriv = new ECSecretBcpgKey(bcpgIn); privateKey = new ECPrivateKeyParameters(pubPk.Algorithm.ToString(), ecdsaPriv.X, ecdsaPub.Oid); break; default: throw new PgpException("unknown public key algorithm encountered"); } return(new PgpPrivateKey(privateKey, KeyId)); } } } catch (PgpException) { throw; } catch (Exception e) { throw new PgpException("Exception constructing key", e); } }