Szyfrowanie kluczem prywatnym RSA w Javie

Próbuję zaszyfrować niektóre treści kluczem prywatnym RSA.

Podążam za tym przykładem: http://www.junkheap.net/content/public_key_encryption_java

ale przekonwertowanie go na użycie kluczy prywatnych zamiast publicznych. Idąc za tym przykładem, myślę, że to, co muszę zrobić, to:

  • odczyt klucza prywatnego w formacie DER
  • Wygeneruj pcks8encodedkeyspec
  • wywołanie generatePrivate () z KeyFactory, aby uzyskać obiekt klucza prywatnego
  • użycie ten obiekt klucza prywatnego z obiektem szyfrowym do szyfrowania

Więc kroki:

Klucz został wygenerowany z openssl za pomocą:

openssl genrsa -aes256 -out private.pem 2048

A następnie został przekonwertowany do formatu DER z:

openssl rsa -in private.pem -outform DER -out private.der

Generuję PKCS8EncodedKeySpec z:

byte[] encodedKey = new byte[(int)inputKeyFile.length()];

try {
    new FileInputStream(inputKeyFile).read(encodedKey);
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
return privateKeySpec;

A następnie wygenerować obiekt klucza prywatnego za pomocą:

PrivateKey pk = null;

try {
    KeyFactory kf = KeyFactory.getInstance(RSA_METHOD);
    pk = kf.generatePrivate(privateKeySpec);
} catch (NoSuchAlgorithmException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (InvalidKeySpecException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
return pk;

Jednak na wezwanie do:

pk = kf.generatePrivate(privateKeySpec);

Otrzymuję:

java.security.spec.InvalidKeySpecException: Unknown key spec.
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275)
at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:237)

Pytania:

  • jest podejściem ogólnym prawda?
  • czy pcks8encodedkeyspec jest odpowiednim klawiszem do użycia?
  • jakieś przemyślenia na temat błędnego klucza spec?
Author: Morten Kristensen, 2009-09-08

5 answers

Po Pierwsze, Nie wiem, dlaczego planujesz użyć Cipher do szyfrowania kluczem prywatnym, a nie podpisywania Signature. Nie jestem pewien, czy wszyscy dostawcy RSA Cipher będą używać odpowiedniego typu bloku do konfiguracji, ale warto spróbować.

Pomijając to, myślę, że próbujesz załadować niestandardowy klucz w formacie OpenSSL. Konwertowanie go do DER za pomocą rsa jest w zasadzie tylko dekodowaniem base-64; struktura klucza nie jest PKCS # 8.

Zamiast genrsa, użyj polecenia openssl pkcs8, Aby przekonwertować wygenerowany klucz na niezaszyfrowany PKCS # 8, DER format:

openssl pkcs8 -topk8 -nocrypt -in private.pem -outform der -out private.der

Spowoduje to utworzenie niezaszyfrowanego klucza prywatnego, który można załadować za pomocą PKCS8EncodedKeySpec.

 6
Author: erickson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-08 03:18:42

Nie można szyfrować kluczem prywatnym. Jeśli JCE ci na to pozwala, to przez przypadek.

Musisz użyć podpisu. Oto fragment kodu, aby to zrobić,

signer = Signature.getInstance("SHA1withRSA");
signer.initSign(privateKey); // PKCS#8 is preferred
signer.update(dataToSign);
byte[] signature = signer.sign();
 10
Author: ZZ Coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-27 16:05:19

To nie przypadek, że szyfrowanie kluczem prywatnym jest dozwolone. Jeśli chcesz złamać podpis na indywidualne hashowanie i szyfrowanie, szyfrowanie kluczem prywatnym jest niezbędne. Powiedzmy, że mam dokument, który muszę podpisać, a mój klucz znajduje się w sieci HSM. Teraz albo przesyłam cały dokument do HSM w celu podpisania, albo mogę utworzyć lokalny hash i przesłać go do HSM w celu samego szyfrowania. Mój wybór będzie zależał od tego, czy lokalne obliczenia hash dają mi lepsze wydajność, a mianowicie delegowane obliczenia hashowe z opóźnieniami sieciowymi.

 4
Author: Kapil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-22 09:15:03

To pytanie jest dość stare, ale ostatnio natknąłem się na problem (implementuję wymagania jakiegoś protokołu, który wymaga szyfrowania kluczem prywatnym). Zacytuję tylko post z forum :

Ostatnio natknąłem się na ten sam problem, przedstawiłem PMR 22265,49 R, A wsparcie IBM po konsultacji z "development" (kimkolwiek oni są) orzekło, że klucze prywatne nie mogą być używane do szyfrowania. Bez względu na to, jak bardzo próbowałem się z nimi kłócić, że klucze prywatne nie powinny być wykorzystywane do ochrony danych, która jest tylko jednym z celów szyfrowania, i że jest całkowicie w porządku, aby używać kluczy prywatnych do szyfrowania, aby osiągnąć nie odrzucenie, byli niezachwiani w ich przekonaniu. Trzeba kochać ludzi, którzy twierdzą, że 2x2=5.

Oto jak obejrzałem ten problem: zasadniczo stworzyłem obiekt klucza publicznego z materiałem kryptograficznym klucza prywatnego. Musisz zrobić odwrotnie, utworzyć obiekt klucza prywatnego za pomocą kryptografii klucza publicznego materiał, aby odszyfrować kluczem publicznym, jeśli chcesz uniknąć wyjątku "klucz publiczny nie może być użyty do odszyfrowania".

RSAPrivateCrtKey privateKey = (RSAPrivateCrtKey) ks.getKey(keyAlias, ksPassword.trim().toCharArray());
RSAPublicKeySpec spec = new RSAPublicKeySpec(
   privateKey.getModulus(),
   privateKey.getPrivateExponent()
);
Key fakePublicKey = KeyFactory.getInstance("RSA").generatePublic(spec);
encryptCipher.init(Cipher.ENCRYPT_MODE, fakePublicKey);
 2
Author: dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-08 14:58:24

Spróbuj tego:

java.security.Security.addProvider(
                     new org.bouncycastle.jce.provider.BouncyCastleProvider()
            );
 0
Author: Jimmy Chan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-06 08:48:16