Загрузить данные открытого ключа из файла

В своем приложении я создаю пару открытого / закрытого ключей и сохраняю их для последующего использования на диске. Загрузка и повторная инициализация закрытого ключа работает нормально, но для закрытого ключа я получаю тип Unknown KeySpec: java.security.spec.PKCS8EncodedKeySpec - и я понятия не имею, почему.

Вот как я создаю и сохраняю ключи (код немного упрощен, чтобы его было легче читать):

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(4096);
KeyPair keyPair = kpg.generateKeyPair();
privKey =keyPair.getPrivate();
pubKey =keyPair.getPublic();        

DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PRIVKEY_FILE,Context.MODE_PRIVATE));
byte[] data=privKey.getEncoded();
out.write(data);
out.close();

DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PUBKEY_FILE,Context.MODE_PRIVATE));
byte[] data=pubKey.getEncoded();
out.write(data);
out.close();

Следующая загрузка закрытого ключа работает нормально:

DataInputStream in=new DataInputStream(ctx.openFileInput(PRIVKEY_FILE));
byte[] data=new byte[in.available()];
in.readFully(data);

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data);
KeyFactory kf = KeyFactory.getInstance("RSA");
privKey = kf.generatePrivate(keySpec);

decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, privKey);

Аналогичный код для открытого ключа с треском проваливается:

DataInputStream in=new DataInputStream(ctx.openFileInput(PUBKEY_FILE));
byte[] data=new byte[in.available()];
in.readFully(data);

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data);
KeyFactory kf = KeyFactory.getInstance("RSA");
pubKey = kf.generatePublic(keySpec); --> here the exception is thrown

encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, pubKey);             

Так что я делаю не так? Как правильно загрузить данные открытых ключей с диска?

Спасибо!


person Elmi    schedule 28.10.2013    source источник


Ответы (1)


Открытый и закрытый ключи кодируются по-разному. В то время как закрытые ключи закодированы в PKCS # 8, открытые ключи - нет. Вместо этого они закодированы в X.509 в соответствии со спецификациями ASN.1.

Описание метода Key.getFormat ():

Возвращает имя основного формата кодировки этого ключа или null, если этот ключ не поддерживает кодировку. Первичный формат кодирования именуется в терминах соответствующего формата данных ASN.1, если существует спецификация ASN.1 для этого ключа. Например, имя формата данных ASN.1 для открытых ключей - SubjectPublicKeyInfo, как определено стандартом X.509; в этом случае возвращается формат «X.509». Точно так же имя формата данных ASN.1 для закрытых ключей - PrivateKeyInfo, как определено стандартом PKCS # 8; в этом случае возвращается формат «PKCS # 8».

В соответствии с этим, вместо того, чтобы читать открытые ключи как PKCS # 8, вы должны читать его как X.509.

Рассмотрите возможность изменения кода чтения открытого ключа с:

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data);

to:

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(data);
person initramfs    schedule 28.10.2013
comment
Вы также можете использовать метод getFormat для распечатки формата кодировки. Например: privKey.getFormat(); - person Sebinjude Shaolin; 31.12.2019