All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider and lightweight API for the Bouncy Castle Cryptography APIs for JDK 1.4.

There is a newer version: 1.79
Show newest version
package org.bouncycastle.crypto.util;

import java.io.IOException;
import java.math.BigInteger;

import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.custom.sec.SecP256R1Curve;
import org.bouncycastle.util.Strings;


/**
 * OpenSSHPublicKeyUtil utility classes for parsing OpenSSH public keys.
 */
public class OpenSSHPublicKeyUtil
{
    private OpenSSHPublicKeyUtil()
    {

    }

    private static final String RSA = "ssh-rsa";
    private static final String ECDSA = "ecdsa";
    private static final String ED_25519 = "ssh-ed25519";
    private static final String DSS = "ssh-dss";

    /**
     * Parse a public key.
     * 

* This method accepts the bytes that are Base64 encoded in an OpenSSH public key file. * * @param encoded The key. * @return An AsymmetricKeyParameter instance. */ public static AsymmetricKeyParameter parsePublicKey(byte[] encoded) { SSHBuffer buffer = new SSHBuffer(encoded); return parsePublicKey(buffer); } /** * Encode a public key from an AsymmetricKeyParameter instance. * * @param cipherParameters The key to encode. * @return the key OpenSSH encoded. * @throws IOException */ public static byte[] encodePublicKey(AsymmetricKeyParameter cipherParameters) throws IOException { BigInteger e; BigInteger n; if (cipherParameters == null) { throw new IllegalArgumentException("cipherParameters was null."); } if (cipherParameters instanceof RSAKeyParameters) { if (cipherParameters.isPrivate()) { throw new IllegalArgumentException("RSAKeyParamaters was for encryption"); } e = ((RSAKeyParameters)cipherParameters).getExponent(); n = ((RSAKeyParameters)cipherParameters).getModulus(); SSHBuilder builder = new SSHBuilder(); builder.writeString(RSA); builder.rawArray(e.toByteArray()); builder.rawArray(n.toByteArray()); return builder.getBytes(); } else if (cipherParameters instanceof ECPublicKeyParameters) { SSHBuilder builder = new SSHBuilder(); String name = null; if (((ECPublicKeyParameters)cipherParameters).getParameters().getCurve() instanceof SecP256R1Curve) { name = "nistp256"; } else { throw new IllegalArgumentException("unable to derive ssh curve name for " + ((ECPublicKeyParameters)cipherParameters).getParameters().getCurve().getClass().getName()); } builder.writeString(ECDSA + "-sha2-" + name); // Magic builder.writeString(name); builder.rawArray(((ECPublicKeyParameters)cipherParameters).getQ().getEncoded(false)); //Uncompressed return builder.getBytes(); } else if (cipherParameters instanceof DSAPublicKeyParameters) { SSHBuilder builder = new SSHBuilder(); builder.writeString(DSS); builder.rawArray(((DSAPublicKeyParameters)cipherParameters).getParameters().getP().toByteArray()); builder.rawArray(((DSAPublicKeyParameters)cipherParameters).getParameters().getQ().toByteArray()); builder.rawArray(((DSAPublicKeyParameters)cipherParameters).getParameters().getG().toByteArray()); builder.rawArray(((DSAPublicKeyParameters)cipherParameters).getY().toByteArray()); return builder.getBytes(); } else if (cipherParameters instanceof Ed25519PublicKeyParameters) { SSHBuilder builder = new SSHBuilder(); builder.writeString(ED_25519); builder.rawArray(((Ed25519PublicKeyParameters)cipherParameters).getEncoded()); return builder.getBytes(); } throw new IllegalArgumentException("unable to convert " + cipherParameters.getClass().getName() + " to private key"); } /** * Parse a public key from an SSHBuffer instance. * * @param buffer containing the SSH public key. * @return A CipherParameters instance. */ public static AsymmetricKeyParameter parsePublicKey(SSHBuffer buffer) { AsymmetricKeyParameter result = null; String magic = Strings.fromByteArray(buffer.readString()); if (RSA.equals(magic)) { BigInteger e = buffer.positiveBigNum(); BigInteger n = buffer.positiveBigNum(); result = new RSAKeyParameters(false, n, e); } else if (DSS.equals(magic)) { BigInteger p = buffer.positiveBigNum(); BigInteger q = buffer.positiveBigNum(); BigInteger g = buffer.positiveBigNum(); BigInteger pubKey = buffer.positiveBigNum(); result = new DSAPublicKeyParameters(pubKey, new DSAParameters(p, q, g)); } else if (magic.startsWith(ECDSA)) { String curveName = Strings.fromByteArray(buffer.readString()); String nameToFind = curveName; if (curveName.startsWith("nist")) { // // NIST names like P-256 are encoded in SSH as nistp256 // nameToFind = curveName.substring(4); nameToFind = nameToFind.substring(0, 1) + "-" + nameToFind.substring(1); } X9ECParameters x9ECParameters = ECNamedCurveTable.getByName(nameToFind); if (x9ECParameters == null) { throw new IllegalStateException("unable to find curve for " + magic + " using curve name " + nameToFind); } // // Extract name of digest from magic string value; // //String digest = magic.split("-")[1]; ECCurve curve = x9ECParameters.getCurve(); byte[] pointRaw = buffer.readString(); result = new ECPublicKeyParameters(curve.decodePoint(pointRaw), new ECDomainParameters(curve, x9ECParameters.getG(), x9ECParameters.getN(), x9ECParameters.getH(), x9ECParameters.getSeed())); } else if (magic.startsWith(ED_25519)) { result = new Ed25519PublicKeyParameters(buffer.readString(), 0); } if (result == null) { throw new IllegalArgumentException("unable to parse key"); } if (buffer.hasRemaining()) { throw new IllegalArgumentException("uncoded key has trailing data"); } return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy