it-swarm-eu.dev

Wie verwende ich OpenSSL-generierte Schlüssel in Java?

Ich habe mein Paar öffentlicher und privater Schlüssel und mein Zertifikat. Diese wurden in OpenSSL erstellt (warum? Weil ich gebeten wurde, dies in OpenSSL zu tun). Jetzt möchte ich diese Dinge verwenden, um eine Java App zu erstellen, die digitale Signaturen verwendet. Wie kann ich meine privaten und öffentlichen Schlüssel zum Ver-/Entschlüsseln von Informationen verwenden (und das Zertifikat verwenden, um festzustellen, ob Daten vorhanden sind)? Was sind die Klassen in Java, mit denen ich das machen kann?

Meine Schlüssel sind im Klartext wie folgt:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDuyg3h0VbP9iZ6RCxSU6x4WX4
anAwedMVUTqF0WHlvHl1Kiqa6N6TiUk23uXAVUX8RwLFjXWHlG0xwW7mGByA2mX9
5oPQpQFu8C70aMuUotGv87iiLi0UKCZV+9wS9rMdg5LHu1mMPilwgOO6MlyTxKem
-----END PUBLIC KEY-----

UPDATE

Ich habe diesen Code erstellt, kann den privaten Schlüssel jedoch immer noch nicht zum Signieren einer Zeichenfolge verwenden.

public void encryptHash(String hashToEncrypt, String pathOfKey, String Algorithm) {
    FileInputStream fis = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int len;

        File f = new File(pathOfKey);

        fis = new FileInputStream(pathOfKey);
        len = 0;
        while((len = fis.read()) != -1){
            baos.write(len);
        }

        KeyFactory kf = KeyFactory.getInstance(Algorithm); //Algorithm = "RSA"
        KeySpec keySpec = new PKCS8EncodedKeySpec(baos.toByteArray());
        baos.close();
        PrivateKey privateKey = kf.generatePrivate(keySpec);  //Here's the exception thrown

        Signature rsaSigner = Signature.getInstance("SHA1withRSA");
        rsaSigner.initSign(privateKey);

        fis = new FileInputStream(hashToEncrypt);
        BufferedInputStream bis = new BufferedInputStream(fis);
        byte[] buffer = new byte[1024];
        len = 0;
        while((len = bis.read(buffer)) >= 0){
            try {
                rsaSigner.update(buffer, 0, len);
            } catch (SignatureException ex) {
                Logger.getLogger(DataEncryptor.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        bis.close();

        byte[] signature = rsaSigner.sign();

        System.out.println(new String(signature));
}

die Ausnahme, die ich bekomme, ist

dic 09, 2011 12:49:02 PM firmaelectronica.DataEncryptor encryptHash
Grave: null
Java.security.spec.InvalidKeySpecException: Java.security.InvalidKeyException: IOException : DER input, Integer tag error
    at Sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.Java:217)
    at Java.security.KeyFactory.generatePrivate(KeyFactory.Java:372)
    at firmaelectronica.DataEncryptor.encryptHash(DataEncryptor.Java:40)
    at firmaelectronica.FirmaElectronica.main(FirmaElectronica.Java:39)
Caused by: Java.security.InvalidKeyException: IOException : DER input, Integer tag error
    at Sun.security.pkcs.PKCS8Key.decode(PKCS8Key.Java:361)
    at Sun.security.pkcs.PKCS8Key.decode(PKCS8Key.Java:367)
    at Sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.Java:91)
    at Sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.Java:75)
    at Sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.Java:316)
    at Sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.Java:213)
    ... 3 more
11
BRabbit27

Wenn Sie einen öffentlichen Schlüssel in dieser Form haben (und nicht in einem Zertifikat), würde ich die Verwendung von BouncyCastle 's PEMReader empfehlen. Die Methode readObject() kann für folgende Formate viel lesen: öffentliche Schlüssel, Zertifikate, private Schlüssel (obwohl Sie die Methode möglicherweise mit einem Kennwort verwenden müssen) ...

Wenn Sie BouncyCastle nicht verwenden möchten, können Sie Zertifikate mit einem CertificateFactory lesen (siehe Beispiele). Mit einem Zertifikat im PEM-Format in einem InputStream:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
Certificate cert = cf.generateCertificate(inputStream);

Wenn Ihr privater Schlüssel eine private PKCS # 8-Struktur im DER-Format ist, können Sie ihn bei privaten Schlüsseln direkt mit PKCS8EncodedKeySpec lesen. Zum Beispiel:

KeyFactory kf = KeyFactory.getInstance("RSA");
// Read privateKeyDerByteArray from DER file.
KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyDerByteArray);
PrivateKey key = kf.generatePrivate(keySpec);

Sie können Ihren privaten Schlüssel mit openssl pkcs8 -topk8 In PKCS # 8 konvertieren (denken Sie daran, -outform DER). Möglicherweise möchten Sie auch die Cipher Suites überprüfen, da möglicherweise nicht alle von beiden Java und OpenSSL).

  • Aus Sicht der Keystore-Nutzung:

Wenn Sie nicht viel für die Handhabung der Schlüssel programmieren möchten, können Sie zwischen Java und OpenSSL) das PKCS # 12-Format verwenden.

Wenn sich die mit OpenSSL erstellten Schlüssel und Zertifikate nicht bereits in einem p12-Container befinden:

openssl pkcs12 -export -in cert.pem -inkey key.pem -out store.p12

Im Allgemeinen können Sie den Keystore-Typ "PKCS12" Von Java direkt verwenden (anstelle von "JKS" standardmäßig).

Bei Bedarf können Sie diesen PKCS12-Keystore mit keytool (Java 6+) in ein anderes Format (z. B. JKS) konvertieren:

keytool -importkeystore -srckeystore store.p12 -srcstoretype PKCS12 \
     -destkeystore store.jks -deststoretype JKS

(Im Wesentlichen die entgegengesetzte Operation wie die in diese Frage .)

Unabhängig davon, ob Sie PEMReader verwenden oder Ihren Schlüssel/Ihr Zertifikat von einem KeyStore laden, sollten Sie in der Lage sein, Instanzen von PrivateKey und zu erhalten Certificate (oder PublicKey direkt).

Sie können überprüfen, ob die Signatur eines Certificate mithilfe des privaten Schlüssels, der mit einem bestimmten öffentlichen Schlüssel übereinstimmt, mithilfe seiner verify(PublicKey) -Methode erstellt wurde.

Mit ihnen können Sie auch die Digital Signature API verwenden. Es ist eine allgemeinere API für jede Dokumentsignatur, und ich würde nicht unbedingt eine Zertifikatsignatur damit überprüfen (ich würde dafür lieber die Zertifizierungspfad-API verwenden, da sie auch die Kette erstellt).

10
Bruno