PGP with non-exportable private key (smart card)

Mar 28, 2016 at 4:44 PM
What would be required to provide an alternate implementation of the RSA portion of PGP using RSACryptoServiceProvider to support using non-exportable private keys for decryption (such as entering a PIN for a smart card)?
Mar 28, 2016 at 11:47 PM
Edited Mar 28, 2016 at 11:52 PM
Requires this hack in crypter\3rd-parties\bccrypto\src\openpgp\PgpPublicKeyEncryptedData.cs Org.BouncyCastle.Bcpg.OpenPgp.PgpPublicKeyEncryptedData RecoverSessionData:
        if (keyData.Algorithm == PublicKeyAlgorithmTag.RsaEncrypt
            || keyData.Algorithm == PublicKeyAlgorithmTag.RsaGeneral)
        {
            byte[] bi = secKeyData[0];

            // hack: use RSACryptoServiceProvider (for non-exportable private keys)
            var key = new byte[bi.Length - 2];
            var rsa = crypter.Program.GetRsaFromCertificateStore();
            Array.Copy(bi, 2, key, 0, key.Length);
            return rsa.Decrypt(key, false);

            cipher.ProcessBytes(bi, 2, bi.Length - 2);
        }
And faking a valid-enough private key in crypter\Program.cs crypter.Program GetPgpPrivateKeyFromRsa:
    private static PgpPrivateKey GetPgpPrivateKeyFromRsa (RSACryptoServiceProvider rsa)
    {
        // hack: use RSACryptoServiceProvider (for non-exportable private keys)
        RSAParameters p = rsa.ExportParameters(false); // was true
        var one = new byte[] {1};
        p = new RSAParameters() { Modulus = p.Modulus, Exponent = p.Exponent, D = one, P = one, Q = one, DP = one, DQ = one, InverseQ = one };
Coordinator
Apr 21 at 5:57 PM
Thank you for your contribution :D