Загрузка PublicKey, созданного из API openSSL Java - PullRequest
2 голосов
/ 03 ноября 2010

Следует реализовать решение с помощью JCE. У меня есть строка открытого ключа, сгенерированная с помощью KeyPairGenerator.

Как мне загрузить это в вызове openSSL Api с использованием PEM_read_bio_RSAPublicKey?Или здесь будет закодирована спецификация x509, как мы можем удалить и сгенерировать публичную версию, совместимую с вызовом openssl api?

try {
    // Get the public/private key pair
    KeyPairGenerator keyGen = KeyPairGenerator
        .getInstance(keyAlgorithm);
    keyGen.initialize(numBits);
    KeyPair keyPair = keyGen.genKeyPair();
    PrivateKey privateKey = keyPair.getPrivate();
    PublicKey publicKey = keyPair.getPublic();

    System.out.println("\n" + "Generating key/value pair using "
        + privateKey.getAlgorithm() + " algorithm");

    // Get the bytes of the public and private keys
    privateKeyBytes = privateKey.getEncoded();
    publicKeyBytes = publicKey.getEncoded();
    try {
        rsa_publickey = new 
            BASE64Encoder().encodeBuffer((keyPair.getPublic()).getEncoded());
    }
    catch(Exception e1)
    {
        e1.printStackTrace();
    }
    System.out.println("PublicKey :"+rsa_publickey);
}
catch(Exception e1)
{
    e1.printStackTrace();
}

1 Ответ

3 голосов
/ 03 ноября 2010

Возможно, вы можете попытаться экспортировать его из Java в формат PEM, который OpenSSL может прочитать, используя Bouncycastle PEMWriter.

РЕДАКТИРОВАТЬ: Например, следующий код:

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.genKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();

// Solution 1: using BouncyCastle's PEMWriter
PEMWriter pemWriter = new PEMWriter(new PrintWriter(System.out));
pemWriter.writeObject(publicKey);
pemWriter.flush();

// Solution 2: using sun.misc.BASE64Encoder
// (and possibly naive 64-character line split)
sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
String encoded = encoder.encode(publicKey.getEncoded());
encoded = encoded.replace("\n", "");
StringBuilder builder = new StringBuilder();
builder.append("-----BEGIN PUBLIC KEY-----");
builder.append("\n");
int i = 0;
while (i < encoded.length()) {
    builder.append(encoded.substring(i,
            Math.min(i + 64, encoded.length())));
    builder.append("\n");
    i += 64;
}
builder.append("-----END PUBLIC KEY-----");
System.out.println(builder);

производит этот вывод:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0CCQ5fdVEEm8u1CrbMXa
FK35/d5MxNjCg7EQZwKsydRhfGhbK+u+iTUiv9rkqhcCucqrMi9eXtqt/QNGreFF
oR5auneeCMgqnXxoX7wjuZ5DBt6qN6ZSe+sAPqSKbvvLUmpBUK9pdOvxegQFGG2d
OUCcQLg2o6vLr9r7ZJDSxdyzCb14i+TEt0TnLjFTkR846dmX41gfU7eacoPxYWoo
Pvhq2huyH0cP8rNJ2/+2BcInjyv5TpLT+m0lYjMar6exgonqRetIJF0Gi7unM+0V
RsBoaBMAsLeqoR5OrCrSKepWbjixjHRMmjBaTYM5wP8DAbjVupUQ9kUwqRTzHTti
XQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0CCQ5fdVEEm8u1CrbMXa
FK35/d5MxNjCg7EQZwKsydRhfGhbK+u+iTUiv9rkqhcCucqrMi9eXtqt/QNGreFF
oR5auneeCMgqnXxoX7wjuZ5DBt6qN6ZSe+sAPqSKbvvLUmpBUK9pdOvxegQFGG2d
OUCcQLg2o6vLr9r7ZJDSxdyzCb14i+TEt0TnLjFTkR846dmX41gfU7eacoPxYWoo
Pvhq2huyH0cP8rNJ2/+2BcInjyv5TpLT+m0lYjMar6exgonqRetIJF0Gi7unM+0V
RsBoaBMAsLeqoR5OrCrSKepWbjixjHRMmjBaTYM5wP8DAbjVupUQ9kUwqRTzHTti
XQIDAQAB
-----END PUBLIC KEY-----

(Если вы хотите сделать это без BouncyCastle, вы можете использовать другой кодировщик base 64, поскольку обычно не рекомендуется использовать sun.* пакеты, которые могут быть недоступны или недоступны на всех JRE.)

Я не пытался загрузить с использованием API OpenSSL, но с OpenSSL в командной строке, когда вы вставляете указанный выше ключ, вы получаете это (обратите внимание, что между разделителями BEGIN / END находится stdin, вставленный в терминал здесь):

$ openssl rsa -inform PEM -pubin -text -noout
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0CCQ5fdVEEm8u1CrbMXa
FK35/d5MxNjCg7EQZwKsydRhfGhbK+u+iTUiv9rkqhcCucqrMi9eXtqt/QNGreFF
oR5auneeCMgqnXxoX7wjuZ5DBt6qN6ZSe+sAPqSKbvvLUmpBUK9pdOvxegQFGG2d
OUCcQLg2o6vLr9r7ZJDSxdyzCb14i+TEt0TnLjFTkR846dmX41gfU7eacoPxYWoo
Pvhq2huyH0cP8rNJ2/+2BcInjyv5TpLT+m0lYjMar6exgonqRetIJF0Gi7unM+0V
RsBoaBMAsLeqoR5OrCrSKepWbjixjHRMmjBaTYM5wP8DAbjVupUQ9kUwqRTzHTti
XQIDAQAB
-----END PUBLIC KEY-----
Modulus (2048 bit):
    00:d0:20:90:e5:f7:55:10:49:bc:bb:50:ab:6c:c5:
    da:14:ad:f9:fd:de:4c:c4:d8:c2:83:b1:10:67:02:
    ac:c9:d4:61:7c:68:5b:2b:eb:be:89:35:22:bf:da:
    e4:aa:17:02:b9:ca:ab:32:2f:5e:5e:da:ad:fd:03:
    46:ad:e1:45:a1:1e:5a:ba:77:9e:08:c8:2a:9d:7c:
    68:5f:bc:23:b9:9e:43:06:de:aa:37:a6:52:7b:eb:
    00:3e:a4:8a:6e:fb:cb:52:6a:41:50:af:69:74:eb:
    f1:7a:04:05:18:6d:9d:39:40:9c:40:b8:36:a3:ab:
    cb:af:da:fb:64:90:d2:c5:dc:b3:09:bd:78:8b:e4:
    c4:b7:44:e7:2e:31:53:91:1f:38:e9:d9:97:e3:58:
    1f:53:b7:9a:72:83:f1:61:6a:28:3e:f8:6a:da:1b:
    b2:1f:47:0f:f2:b3:49:db:ff:b6:05:c2:27:8f:2b:
    f9:4e:92:d3:fa:6d:25:62:33:1a:af:a7:b1:82:89:
    ea:45:eb:48:24:5d:06:8b:bb:a7:33:ed:15:46:c0:
    68:68:13:00:b0:b7:aa:a1:1e:4e:ac:2a:d2:29:ea:
    56:6e:38:b1:8c:74:4c:9a:30:5a:4d:83:39:c0:ff:
    03:01:b8:d5:ba:95:10:f6:45:30:a9:14:f3:1d:3b:
    62:5d
Exponent: 65537 (0x10001)

EDIT: Если вы хотите экспортировать что-то в BEGIN RSA PUBLIC KEY, вы можете попробовать что-то вроде этого:

RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
RSAPublicKeyStructure pubkeyStruct = new RSAPublicKeyStructure(
    rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent());
pubkeyStruct.getDEREncoded(); // base64-encode this between the delimiters
...