private (string certificate, string key) TransformPfx(IPasswordFinder passwordFinder) { var certOutput = new StringWriter(); var keyOutput = new StringWriter(); using (var input = File.OpenRead(CertificatePath)) { var certWriter = new PemWriter(certOutput); var keyWriter = new PemWriter(keyOutput); var store = new Pkcs12Store(input, passwordFinder.GetPassword()); foreach (string alias in store.Aliases) { var cert = store.GetCertificate(alias); if (cert != null) { certWriter.WriteObject(cert.Certificate); } var key = store.GetKey(alias); if (key != null && key.Key.IsPrivate) { keyWriter.WriteObject(key.Key); } } } return(certOutput.ToString(), keyOutput.ToString()); }
/** * create the secret key needed for this object, fetching the password */ private ICipherParameters GetKey( string algorithm, int keyLength, byte[] salt) { if (pFinder == null) { throw new InvalidOperationException("No password finder specified, but a password is required"); } char[] password = pFinder.GetPassword(); if (password == null) { throw new IOException("Password is null, but a password is required"); } OpenSslPbeParametersGenerator pGen = new OpenSslPbeParametersGenerator(); pGen.Init(PbeParametersGenerator.Pkcs5PasswordToBytes(password), salt); return(pGen.GenerateDerivedParameters(keyLength * 8)); }
/** * Read a Key Pair */ private object ReadPrivateKey(PemObject pemObject) { // // extract the key // Debug.Assert(pemObject.Type.EndsWith("PRIVATE KEY")); string type = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); byte[] keyBytes = pemObject.Content; IDictionary fields = Platform.CreateHashtable(); foreach (PemHeader header in pemObject.Headers) { fields[header.Name] = header.Value; } string procType = (string)fields["Proc-Type"]; if (procType == "4,ENCRYPTED") { if (pFinder == null) { throw new PasswordException("No password finder specified, but a password is required"); } char[] password = pFinder.GetPassword(); if (password == null) { throw new PasswordException("Password is null, but a password is required"); } string dekInfo = (string)fields["DEK-Info"]; string[] tknz = dekInfo.Split(','); string dekAlgName = tknz[0].Trim(); byte[] iv = Hex.Decode(tknz[1].Trim()); keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); } try { AsymmetricKeyParameter pubSpec, privSpec; Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(keyBytes); switch (type) { case "RSA": { if (seq.Count != 9) { throw new PemException("malformed sequence in RSA private key"); } RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); privSpec = new RsaPrivateCrtKeyParameters( rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); break; } case "DSA": { if (seq.Count != 6) { throw new PemException("malformed sequence in DSA private key"); } // TODO Create an ASN1 object somewhere for this? //DerInteger v = (DerInteger)seq[0]; DerInteger p = (DerInteger)seq[1]; DerInteger q = (DerInteger)seq[2]; DerInteger g = (DerInteger)seq[3]; DerInteger y = (DerInteger)seq[4]; DerInteger x = (DerInteger)seq[5]; DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); privSpec = new DsaPrivateKeyParameters(x.Value, parameters); pubSpec = new DsaPublicKeyParameters(y.Value, parameters); break; } case "EC": { ECPrivateKeyStructure pKey = new ECPrivateKeyStructure(seq); AlgorithmIdentifier algId = new AlgorithmIdentifier( X9ObjectIdentifiers.IdECPublicKey, pKey.GetParameters()); PrivateKeyInfo privInfo = new PrivateKeyInfo(algId, pKey.ToAsn1Object()); // TODO Are the keys returned here ECDSA, as Java version forces? privSpec = PrivateKeyFactory.CreateKey(privInfo); DerBitString pubKey = pKey.GetPublicKey(); if (pubKey != null) { SubjectPublicKeyInfo pubInfo = new SubjectPublicKeyInfo(algId, pubKey.GetBytes()); // TODO Are the keys returned here ECDSA, as Java version forces? pubSpec = PublicKeyFactory.CreateKey(pubInfo); } else { pubSpec = ECKeyPairGenerator.GetCorrespondingPublicKey( (ECPrivateKeyParameters)privSpec); } break; } case "ENCRYPTED": { char[] password = pFinder.GetPassword(); if (password == null) { throw new PasswordException("Password is null, but a password is required"); } return(PrivateKeyFactory.DecryptKey(password, EncryptedPrivateKeyInfo.GetInstance(seq))); } case "": { return(PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(seq))); } default: throw new ArgumentException("Unknown key type: " + type, "type"); } return(new AsymmetricCipherKeyPair(pubSpec, privSpec)); } catch (IOException e) { throw e; } catch (Exception e) { throw new PemException( "problem creating " + type + " private key: " + e.ToString()); } }
/** * Read a Key Pair */ private AsymmetricCipherKeyPair ReadKeyPair( string type, string endMarker) { // // extract the key // IDictionary fields = new Hashtable(); byte[] keyBytes = ReadBytesAndFields(endMarker, fields); string procType = (string)fields["Proc-Type"]; if (procType == "4,ENCRYPTED") { if (pFinder == null) { throw new PasswordException("No password finder specified, but a password is required"); } char[] password = pFinder.GetPassword(); if (password == null) { throw new PasswordException("Password is null, but a password is required"); } string dekInfo = (string)fields["DEK-Info"]; string[] tknz = dekInfo.Split(','); string dekAlgName = tknz[0].Trim(); byte[] iv = Hex.Decode(tknz[1].Trim()); keyBytes = PemUtilities.Crypt(false, keyBytes, password, dekAlgName, iv); } try { AsymmetricKeyParameter pubSpec, privSpec; Asn1Sequence seq = (Asn1Sequence)Asn1Object.FromByteArray(keyBytes); switch (type) { case "RSA": { RsaPrivateKeyStructure rsa = new RsaPrivateKeyStructure(seq); pubSpec = new RsaKeyParameters(false, rsa.Modulus, rsa.PublicExponent); privSpec = new RsaPrivateCrtKeyParameters( rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient); break; } case "DSA": { // TODO Create an ASN1 object somewhere for this? //DerInteger v = (DerInteger)seq[0]; DerInteger p = (DerInteger)seq[1]; DerInteger q = (DerInteger)seq[2]; DerInteger g = (DerInteger)seq[3]; DerInteger y = (DerInteger)seq[4]; DerInteger x = (DerInteger)seq[5]; DsaParameters parameters = new DsaParameters(p.Value, q.Value, g.Value); privSpec = new DsaPrivateKeyParameters(x.Value, parameters); pubSpec = new DsaPublicKeyParameters(y.Value, parameters); break; } default: throw new ArgumentException("Unknown key type: " + type, "type"); } return(new AsymmetricCipherKeyPair(pubSpec, privSpec)); } catch (Exception e) { throw new PemException( "problem creating " + type + " private key: " + e.ToString()); } }
private object ReadPrivateKey(PemObject pemObject) { string text = pemObject.Type.Substring(0, pemObject.Type.Length - "PRIVATE KEY".Length).Trim(); byte[] array = pemObject.Content; IDictionary dictionary = Platform.CreateHashtable(); foreach (PemHeader header in pemObject.Headers) { dictionary[header.Name] = header.Value; } string a = (string)dictionary["Proc-Type"]; if (a == "4,ENCRYPTED") { if (pFinder == null) { throw new PasswordException("No password finder specified, but a password is required"); } char[] password = pFinder.GetPassword(); if (password == null) { throw new PasswordException("Password is null, but a password is required"); } string text2 = (string)dictionary["DEK-Info"]; string[] array2 = text2.Split(','); string dekAlgName = array2[0].Trim(); byte[] iv = Hex.Decode(array2[1].Trim()); array = PemUtilities.Crypt(encrypt: false, array, password, dekAlgName, iv); } try { Asn1Sequence instance = Asn1Sequence.GetInstance(array); AsymmetricKeyParameter publicParameter; AsymmetricKeyParameter asymmetricKeyParameter; switch (text) { case "RSA": { if (instance.Count != 9) { throw new PemException("malformed sequence in RSA private key"); } RsaPrivateKeyStructure instance2 = RsaPrivateKeyStructure.GetInstance(instance); publicParameter = new RsaKeyParameters(isPrivate: false, instance2.Modulus, instance2.PublicExponent); asymmetricKeyParameter = new RsaPrivateCrtKeyParameters(instance2.Modulus, instance2.PublicExponent, instance2.PrivateExponent, instance2.Prime1, instance2.Prime2, instance2.Exponent1, instance2.Exponent2, instance2.Coefficient); break; } case "DSA": { if (instance.Count != 6) { throw new PemException("malformed sequence in DSA private key"); } DerInteger derInteger = (DerInteger)instance[1]; DerInteger derInteger2 = (DerInteger)instance[2]; DerInteger derInteger3 = (DerInteger)instance[3]; DerInteger derInteger4 = (DerInteger)instance[4]; DerInteger derInteger5 = (DerInteger)instance[5]; DsaParameters parameters = new DsaParameters(derInteger.Value, derInteger2.Value, derInteger3.Value); asymmetricKeyParameter = new DsaPrivateKeyParameters(derInteger5.Value, parameters); publicParameter = new DsaPublicKeyParameters(derInteger4.Value, parameters); break; } case "EC": { ECPrivateKeyStructure instance3 = ECPrivateKeyStructure.GetInstance(instance); AlgorithmIdentifier algID = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, instance3.GetParameters()); PrivateKeyInfo keyInfo = new PrivateKeyInfo(algID, instance3.ToAsn1Object()); asymmetricKeyParameter = PrivateKeyFactory.CreateKey(keyInfo); DerBitString publicKey = instance3.GetPublicKey(); if (publicKey != null) { SubjectPublicKeyInfo keyInfo2 = new SubjectPublicKeyInfo(algID, publicKey.GetBytes()); publicParameter = PublicKeyFactory.CreateKey(keyInfo2); } else { publicParameter = ECKeyPairGenerator.GetCorrespondingPublicKey((ECPrivateKeyParameters)asymmetricKeyParameter); } break; } case "ENCRYPTED": { char[] password2 = pFinder.GetPassword(); if (password2 == null) { throw new PasswordException("Password is null, but a password is required"); } return(PrivateKeyFactory.DecryptKey(password2, EncryptedPrivateKeyInfo.GetInstance(instance))); } case "": return(PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(instance))); default: throw new ArgumentException("Unknown key type: " + text, "type"); } return(new AsymmetricCipherKeyPair(publicParameter, asymmetricKeyParameter)); } catch (IOException ex) { throw ex; } catch (Exception ex2) { throw new PemException("problem creating " + text + " private key: " + ex2.ToString()); } }