private static AsymmetricCipherKeyPair CreateCipherKeyPair(
PublicKeyAlgorithm algorithm,
byte[] publicKeyBlob, byte[] privateKeyBlob)
{
var parser = new BlobParser(publicKeyBlob);
var publicKey = parser.ReadSsh2PublicKeyData();
parser = new BlobParser(privateKeyBlob);
switch (algorithm) {
case PublicKeyAlgorithm.SSH_RSA:
var rsaPublicKeyParams = (RsaKeyParameters)publicKey;
var d = new BigInteger(1, parser.ReadBlob());
var p = new BigInteger(1, parser.ReadBlob());
var q = new BigInteger(1, parser.ReadBlob());
var inverseQ = new BigInteger(1, parser.ReadBlob());
/* compute missing parameters */
var dp = d.Remainder(p.Subtract(BigInteger.One));
var dq = d.Remainder(q.Subtract(BigInteger.One));
RsaPrivateCrtKeyParameters rsaPrivateKeyParams =
new RsaPrivateCrtKeyParameters(rsaPublicKeyParams.Modulus,
rsaPublicKeyParams.Exponent, d, p, q, dp, dq, inverseQ);
return new AsymmetricCipherKeyPair(rsaPublicKeyParams,
rsaPrivateKeyParams);
case PublicKeyAlgorithm.SSH_DSS:
var dsaPublicKeyParams = (DsaPublicKeyParameters)publicKey;
var x = new BigInteger(1, parser.ReadBlob());
DsaPrivateKeyParameters dsaPrivateKeyParams =
new DsaPrivateKeyParameters(x, dsaPublicKeyParams.Parameters);
return new AsymmetricCipherKeyPair(dsaPublicKeyParams,
dsaPrivateKeyParams);
case PublicKeyAlgorithm.ED25519:
var ed25596PublicKey = (Ed25519PublicKeyParameter)publicKey;
byte[] privBlob = parser.ReadBlob();
byte[] privSig = new byte[64];
// OpenSSH's "private key" is actually the private key with the public key tacked on ...
Array.Copy(privBlob, 0, privSig, 0, 32);
Array.Copy(ed25596PublicKey.Key, 0, privSig, 32, 32);
var ed25596PrivateKey = new Ed25519PrivateKeyParameter(privSig);
return new AsymmetricCipherKeyPair(ed25596PublicKey, ed25596PrivateKey);
case PublicKeyAlgorithm.ECDSA_SHA2_NISTP256:
case PublicKeyAlgorithm.ECDSA_SHA2_NISTP384:
case PublicKeyAlgorithm.ECDSA_SHA2_NISTP521:
var ecPublicKeyParams = (ECPublicKeyParameters)publicKey;
var ecdsaPrivate = new BigInteger(1, parser.ReadBlob());
ECPrivateKeyParameters ecPrivateKeyParams =
new ECPrivateKeyParameters(ecdsaPrivate, ecPublicKeyParams.Parameters);
return new AsymmetricCipherKeyPair(ecPublicKeyParams, ecPrivateKeyParams);
default:
// unsupported encryption algorithm
throw new PpkFormatterException(PpkFormatterException.PpkErrorType.PublicKeyEncryption);
}
}