2013-03-11 5 views
8

Sto cercando di caricare una chiave privata RSA generata con SSL in Java, il mio codice è:carico di una chiave RSA privata in Java (errore di parsing algida, non una sequenza)

generare la chiave:

openssl genrsa -out mykey.pem 1024 

Risultato:

-----BEGIN RSA PRIVATE KEY----- 
MIICXAIBAAKBgQCUibP4fY2PA/sGMKMbU6usuIGcOAqgQjD6c2ylVo05Oz7pgjnE 
+O0l2MFRUYUGT5KKk/W+0cAXkxaQHE3n8A8X1mHT8eMDmWnzz0PeYjDE8LQmAw8R 
Y2FnVKFAB36BIjdb5FsZmCk5QYKU5+nWLMqH/j/IR5AyX5wR2SMoslUg2QIDAQAB 
AoGAeJ1s7638IhLIZtldyRXjRKi6ToFPV50IKodJxOSIXt3WE0V05ZaA84eUSxUY 
IOzCgRbuqVmnUz1USAdD18AecC8qc7tXTRALLy7q8fxklPwmGPUOvTFmI7gRMUnv 
cWrq1gySk3SKpj0YmWnuY9Xmd2+xoWLzUeFD1CROY5OTjIECQQDDlp1+Al7+duR0 
XyMlkWLIk0nIbkQ5zlTAEipzmaeTSOJi6YG3EMMz3AGuZb7tw6HFxWqeg1hyKJ+T 
cTM3WTdJAkEAwmrCDKE29n3wFOBKsZZFQbDgVOUXCBs2ubEI+ALe1DJU5BlfnrhJ 
OINRCNgnwSFNbwxDTkDpR6J6Av2ElAvNEQJAV0dVvk5Wj50Ecz2lFHWdLD41taAn 
B9igDxnMIcvWcK4cf+ENhmCPiwvJIEa8/aLIBNYErvmTtVWVaBkirrc8KQJABr+z 
+sJB6S6X/fGHRkDkKJKeRvQo54QiUzHdENbwq0cQAVcMJbNZ/1c3oen2/1JLoNY5 
I+dG8dCnEaGBT65VMQJBAIDqH1Kqs5tb51cpt6h9ot31SUVud5pSML/babwp3pRs 
1s6poreym4PkAyRug0Dgcj1zVLt25TlOHvrL9r3Swq8= 
-----END RSA PRIVATE KEY----- 

carico:

String privKeyPEM=readFile("mykey.pem"); 
privKeyPEM= privKeyPEM.replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("\n", ""); 
// Remove the first and last lines 
privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 
System.out.println(privKeyPEM); 

// Base64 decode the data 
byte [] encoded = Base64.decode(privKeyPEM); 

// PKCS8 decode the encoded RSA private key 
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
PrivateKey privKey = kf.generatePrivate(keySpec); 

// Display the results 
System.out.println(privKey); 

e viene generata IOException : algid parse error, not a sequence. Dov'è l'errore?

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(Unknown Source) 
at java.security.KeyFactory.generatePrivate(Unknown Source) 
at base54.encrypt.RSAToy.main(RSAToy.java:36) 
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence 
at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
at sun.security.pkcs.PKCS8Key.decode(Unknown Source) 
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(Unknown Source) 
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(Unknown Source) 
at sun.security.rsa.RSAKeyFactory.generatePrivate(Unknown Source) 
+0

forse si potrebbe mostrare i primi 10 byte di uscita della decodifica Base64 in esadecimale? –

+5

openssl pkcs8 -topk8 ... è tuo amico. openssl rsa genera chiavi bare rsa non PKCS8. –

+2

Potresti postarla come risposta, nullix? Ho appena verificato che questa è una chiave privata formattata PKCS # 1 (solo il modulo, l'esponente pubblico e privato e i parametri CRT) –

risposta

-1

si potrebbe ancora caricare le chiavi, se necessario,

public static PublicKey bigIntegerToPublicKey(BigInteger e, BigInteger m) { 
    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PublicKey pubKey = fact.generatePublic(keySpec); 
    return pubKey; 
} 

public static PrivateKey bigIntegerToPrivateKey(BigInteger e, BigInteger m) { 
    RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e); 
    KeyFactory fact = KeyFactory.getInstance("RSA"); 
    PrivateKey privKey = fact.generatePrivate(keySpec); 
    return privKey; 
} 

tutto ciò che serve è il modulo e l'esponente.

+2

Da dove vengono definiti i parametri eM? – jonney

+0

quelli sono l'esponente e il modulo dai corrispondenti tasti rsa. Dalla PrivateKey-Class puoi usare getPrivateExponent() e getModulus() e lo stesso da PublicKey. È possibile generare entrambi con "KeyPairGenerator kpg = KeyPairGenerator.getInstance (" RSA "); kpg.initialize (2048); KeyPair kp = kpg.genKeyPair();" – hellfiend

+0

Cosa succede se una chiave è già stata generata? cioè se qualcuno ti invia la tua chiave pubblica in una risposta stringa? come genereresti una chiave pubblica? – jonney

4

Si ottiene questo errore perché si sta leggendo un file di chiave PKCS # 8, ma il file ha un formato PKCS # 1 (PKCS # 1 ha l'intestazione BEGIN RSA PRIVATE KEY mentre PKCS # 8 ha l'intestazione BEGIN PRIVATE KEY).

Per leggere sia PKCS # 8 file PEM PKCS # 1 e, io uso il codice sorgente di org.apache.jmeter.protocol.oauth.sampler.PrivateKeyReader di jmeter:

PrivateKey pk = (new PrivateKeyReader ("/ path/to/myfile.der")) getPrivateKey().;

+0

Potresti aggiungere un esempio di utilizzo, ad esempio, detaillare come utilizzare il codice sorgente di Apache per caricare una chiave PKCS # 1 da un array di byte e inserirla in un'istanza PrivateKey? – arik

+0

Dovresti leggere PrivateKeyReader che legge il file in un byte [], quindi crea PrivateKey. –

14

In seguito alla risposta di Julien Kronegg, se si verifica questo errore perché il file ha un formato PKCS # 1, è possibile utilizzare i seguenti passaggi per convertirlo in un file PKCS # 8.

In primo luogo, salvare il PKCS # 1 file di chiave in un file chiamato priv1.pem:

-----BEGIN RSA PRIVATE KEY----- 
[...] 
-----END RSA PRIVATE KEY----- 

Poi, eseguire il seguente comando:

openssl pkcs8 -topk8 -inform PEM -outform PEM -in priv1.pem -out priv8.pem -nocrypt 

Questo produce un file chiamato priv8.pem, che è la vostra file chiave in formato PKCS # 8:

-----BEGIN PRIVATE KEY----- 
[...] 
-----END PRIVATE KEY----- 

Io uso questo da J ava come segue:

String PRIVATE_RSA_KEY_PKCS8 = 
    "-----BEGIN PRIVATE KEY-----\n" + 
    "MDSTofml23d....\n" + 
    [...] + 
    "-----END PRIVATE KEY-----\n"; 
String key = PRIVATE_RSA_KEY_PKCS8 
    .replace("-----BEGIN PRIVATE KEY-----\n", "") 
    .replace("\n-----END PRIVATE KEY-----\n", ""); 
PKCS8EncodedKeySpec keySpec = 
    new PKCS8EncodedKeySpec(DatatypeConverter.parseBase64Binary(key)); 
try { 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
    PrivateKey privateKey = keyFactory.generatePrivate(keySpec); 
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); 
    cipher.init(Cipher.DECRYPT_MODE, privateKey); 
    byte[] bytes = parseBase64Binary(encryptedNodeIdentifier); 
    byte[] decryptedData = cipher.doFinal(bytes); 
    return new String(decryptedData); 
} catch (GeneralSecurityException e) { 
    return ""; 
} 
+2

Grazie, questo è stato molto utile. –

1

In alternativa è possibile convertire il mykey.pem in formato DER e utilizzare il codice esistente. Di seguito è riportato il comando openssl per farlo


openssl pkcs8 -topk8 -inform PEM -outform DER -in mykey.pem -out mykey.der -nocrypt 

Il nuovo file formattati sarà qualche cosa come



3082 0276 0201 0030 0d06 092a 8648 86f7 
0d01 0101 0500 0482 0260 3082 025c 0201 
0002 8181 00a9 0689 7676 2a63 5779 e4e8 
4bb5 8e53 bc44 a975 8254 cb64 5cf2 1499 
ad1c 6c35 6027 e357 ac09 0421 2b4b ddb4 
1be3 a688 a848 5618 bce8 25d0 2cf2 972b 
3801 a023 d6ee d824 4cfb 078f dad8 4317 
fc9d 9468 27cc 2f08 f755 3293 76cb 3c60 
4302 1c59 a8e8 5ac9 0576 8bb0 6bbb 8f1a 
092d 7884 a405 c775 a8ca 7a2c 8037 435c 
557a c9f0 a702 0301 0001 0281 8100 8462 
6c53 ee25 30fd 98a9 230f f939 6a78 30c7 
1114 6d59 8858 0bfa fa8a 4d92 ab13 8eea 
4f06 9d61 30a1 7aa0 40aa ff58 b5fc 27fb 
d710 4e3b 1f9b b4bd 95ca 1deb d165 063a 
da5c 383d e428 cbf6 1f62 4549 5b96 ee2d 
b811 4cff c849 9637 67e4 a5d5 1c75 f13b 
8ddd b212 ba2f 7118 885e bc98 cab6 5434 
d1e8 2a33 c408 1186 be05 6074 7431 0241 
00d8 a1e2 d382 d52a 372e 0a62 807f 8283 
e615 c7a7 180b e21c b6ce cd55 940f 542b 
903f 86a0 e488 74b2 d69d d5d1 27d9 4079 
72a2 80f8 c105 3e19 309b dd78 4dbe 440d 
0d02 4100 c7bd e5fd ccee 60b2 cbc0 7520 
53c1 6442 9f11 e0d0 969f 6315 41cd 7b3c 
c279 cebe 4025 a4f4 97c9 6d1b c48f 6f01 
cd3b e849 33e6 5f13 7fb6 2780 22d1 f2da 

11

Ecco un codice di org.apache.jmeter.protocol.oauth.sampler.PrivateKeyReader modificata utilizzando Java solo runtime. Funziona per me, può caricare il file di chiave privata PKCS # 1 o PKCS # 8 e restituisce una classe PrivateKey. (Per favore fatemi sapere se ho incasinato qualcosa mentre copia/incolla).

Utilizzare in questo modo: PrivateKey pk = (nuovo PrivateKeyReader ("/ percorso/a/myfile.der")). GetPrivateKey();

/** 
* 
*/ 
package default; 

/**************************************************************************** 
* Copyright (c) 1998-2010 AOL Inc. 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
* 
* Modified 23-4-2015 misterti 
* 
****************************************************************************/ 

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.math.BigInteger; 
import java.security.GeneralSecurityException; 
import java.security.KeyFactory; 
import java.security.PrivateKey; 
import java.security.spec.KeySpec; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.security.spec.RSAPrivateCrtKeySpec; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.Map; 

import javax.xml.bind.DatatypeConverter; 


/** 
* Class for reading RSA private key from PEM file. It uses 
* the JMeter FileServer to find the file. So the file should 
* be located in the same directory as the test plan if the 
* path is relative. 
* 
* <p/>There is a cache so each file is only read once. If file 
* is changed, it will not take effect until the program 
* restarts. 
* 
* <p/>It can read PEM files with PKCS#8 or PKCS#1 encodings. 
* It doesn't support encrypted PEM files. 
* 
*/ 
public class PrivateKeyReader { 

    // Private key file using PKCS #1 encoding 
    public static final String P1_BEGIN_MARKER 
    = "-----BEGIN RSA PRIVATE KEY"; //$NON-NLS-1$ 
    public static final String P1_END_MARKER 
     = "-----END RSA PRIVATE KEY"; //$NON-NLS-1$ 

    // Private key file using PKCS #8 encoding 
    public static final String P8_BEGIN_MARKER 
    = "-----BEGIN PRIVATE KEY"; //$NON-NLS-1$ 
    public static final String P8_END_MARKER 
     = "-----END PRIVATE KEY"; //$NON-NLS-1$ 

    private static Map<String, PrivateKey> keyCache = 
    Collections.synchronizedMap(new HashMap<String, PrivateKey>()); 

    protected final String fileName; 

    /** 
    * Create a PEM private key file reader. 
    * 
    * @param fileName The name of the PEM file 
    */ 
    public PrivateKeyReader(String fileName) { 
    this.fileName = fileName; 
    } 

    /** 
    * Get a Private Key for the file. 
    * 
    * @return Private key 
    * @throws IOException 
    */ 

    public PrivateKey getPrivateKey() throws IOException, GeneralSecurityException 
    { 
    PrivateKey key = null; 
    FileInputStream fis = null; 
    boolean isRSAKey = false; 
    try { 
     File f = new File(fileName); 
     fis = new FileInputStream(f); 

     BufferedReader br = new BufferedReader(new InputStreamReader(fis)); 
     StringBuilder builder = new StringBuilder(); 
     boolean inKey = false; 
     for (String line = br.readLine(); line != null; line = br.readLine()) { 
      if (!inKey) { 
       if (line.startsWith("-----BEGIN ") && 
         line.endsWith(" PRIVATE KEY-----")) { 
        inKey = true; 
        isRSAKey = line.contains("RSA"); 
       } 
       continue; 
      } 
      else { 
       if (line.startsWith("-----END ") && 
         line.endsWith(" PRIVATE KEY-----")) { 
        inKey = false; 
        isRSAKey = line.contains("RSA"); 
        break; 
       } 
       builder.append(line); 
      } 
     } 
     KeySpec keySpec = null; 
     byte[] encoded = DatatypeConverter.parseBase64Binary(builder.toString());   
     if (isRSAKey) 
     { 
      keySpec = getRSAKeySpec(encoded); 
     } 
     else 
     { 
      keySpec = new PKCS8EncodedKeySpec(encoded); 
     } 
     KeyFactory kf = KeyFactory.getInstance("RSA"); 
     key = kf.generatePrivate(keySpec); 
    } finally { 
     if (fis != null) 
     try { fis.close(); } catch (Exception ign) {} } 
    return key; 
    } 


    /** 
    * Convert PKCS#1 encoded private key into RSAPrivateCrtKeySpec. 
    * 
    * <p/>The ASN.1 syntax for the private key with CRT is 
    * 
    * <pre> 
    * -- 
    * -- Representation of RSA private key with information for the CRT algorithm. 
    * -- 
    * RSAPrivateKey ::= SEQUENCE { 
    * version   Version, 
    * modulus   INTEGER, -- n 
    * publicExponent INTEGER, -- e 
    * privateExponent INTEGER, -- d 
    * prime1   INTEGER, -- p 
    * prime2   INTEGER, -- q 
    * exponent1   INTEGER, -- d mod (p-1) 
    * exponent2   INTEGER, -- d mod (q-1) 
    * coefficient  INTEGER, -- (inverse of q) mod p 
    * otherPrimeInfos OtherPrimeInfos OPTIONAL 
    * } 
    * </pre> 
    * 
    * @param keyBytes PKCS#1 encoded key 
    * @return KeySpec 
    * @throws IOException 
    */ 

    private RSAPrivateCrtKeySpec getRSAKeySpec(byte[] keyBytes) throws IOException { 

     DerParser parser = new DerParser(keyBytes); 

     Asn1Object sequence = parser.read(); 
     if (sequence.getType() != DerParser.SEQUENCE) 
      throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$ 

     // Parse inside the sequence 
     parser = sequence.getParser(); 

     parser.read(); // Skip version 
     BigInteger modulus = parser.read().getInteger(); 
     BigInteger publicExp = parser.read().getInteger(); 
     BigInteger privateExp = parser.read().getInteger(); 
     BigInteger prime1 = parser.read().getInteger(); 
     BigInteger prime2 = parser.read().getInteger(); 
     BigInteger exp1 = parser.read().getInteger(); 
     BigInteger exp2 = parser.read().getInteger(); 
     BigInteger crtCoef = parser.read().getInteger(); 

     RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(
      modulus, publicExp, privateExp, prime1, prime2, 
      exp1, exp2, crtCoef); 

     return keySpec; 
    }  
} 

/** 
* A bare-minimum ASN.1 DER decoder, just having enough functions to 
* decode PKCS#1 private keys. Especially, it doesn't handle explicitly 
* tagged types with an outer tag. 
* 
* <p/>This parser can only handle one layer. To parse nested constructs, 
* get a new parser for each layer using <code>Asn1Object.getParser()</code>. 
* 
* <p/>There are many DER decoders in JRE but using them will tie this 
* program to a specific JCE/JVM. 
* 
* @author zhang 
* 
*/ 
class DerParser { 

    // Classes 
    public final static int UNIVERSAL = 0x00; 
    public final static int APPLICATION = 0x40; 
    public final static int CONTEXT = 0x80; 
    public final static int PRIVATE = 0xC0; 

    // Constructed Flag 
    public final static int CONSTRUCTED = 0x20; 

    // Tag and data types 
    public final static int ANY = 0x00; 
    public final static int BOOLEAN = 0x01; 
    public final static int INTEGER = 0x02; 
    public final static int BIT_STRING = 0x03; 
    public final static int OCTET_STRING = 0x04; 
    public final static int NULL = 0x05; 
    public final static int OBJECT_IDENTIFIER = 0x06; 
    public final static int REAL = 0x09; 
    public final static int ENUMERATED = 0x0a; 
    public final static int RELATIVE_OID = 0x0d; 

    public final static int SEQUENCE = 0x10; 
    public final static int SET = 0x11; 

    public final static int NUMERIC_STRING = 0x12; 
    public final static int PRINTABLE_STRING = 0x13; 
    public final static int T61_STRING = 0x14; 
    public final static int VIDEOTEX_STRING = 0x15; 
    public final static int IA5_STRING = 0x16; 
    public final static int GRAPHIC_STRING = 0x19; 
    public final static int ISO646_STRING = 0x1A; 
    public final static int GENERAL_STRING = 0x1B; 

    public final static int UTF8_STRING = 0x0C; 
    public final static int UNIVERSAL_STRING = 0x1C; 
    public final static int BMP_STRING = 0x1E; 

    public final static int UTC_TIME = 0x17; 
    public final static int GENERALIZED_TIME = 0x18; 

    protected InputStream in; 

    /** 
    * Create a new DER decoder from an input stream. 
    * 
    * @param in 
    *   The DER encoded stream 
    */ 
    public DerParser(InputStream in) throws IOException { 
    this.in = in; 
    } 

    /** 
    * Create a new DER decoder from a byte array. 
    * 
    * @param The 
    *   encoded bytes 
    * @throws IOException 
    */ 
    public DerParser(byte[] bytes) throws IOException { 
    this(new ByteArrayInputStream(bytes)); 
    } 

    /** 
    * Read next object. If it's constructed, the value holds 
    * encoded content and it should be parsed by a new 
    * parser from <code>Asn1Object.getParser</code>. 
    * 
    * @return A object 
    * @throws IOException 
    */ 
    public Asn1Object read() throws IOException { 
    int tag = in.read(); 

    if (tag == -1) 
     throw new IOException("Invalid DER: stream too short, missing tag"); //$NON-NLS-1$ 

    int length = getLength(); 

    byte[] value = new byte[length]; 
    int n = in.read(value); 
    if (n < length) 
     throw new IOException("Invalid DER: stream too short, missing value"); //$NON-NLS-1$ 

    Asn1Object o = new Asn1Object(tag, length, value); 

    return o; 
    } 

    /** 
    * Decode the length of the field. Can only support length 
    * encoding up to 4 octets. 
    * 
    * <p/>In BER/DER encoding, length can be encoded in 2 forms, 
    * <ul> 
    * <li>Short form. One octet. Bit 8 has value "0" and bits 7-1 
    * give the length. 
    * <li>Long form. Two to 127 octets (only 4 is supported here). 
    * Bit 8 of first octet has value "1" and bits 7-1 give the 
    * number of additional length octets. Second and following 
    * octets give the length, base 256, most significant digit first. 
    * </ul> 
    * @return The length as integer 
    * @throws IOException 
    */ 
    private int getLength() throws IOException { 

    int i = in.read(); 
    if (i == -1) 
     throw new IOException("Invalid DER: length missing"); //$NON-NLS-1$ 

    // A single byte short length 
    if ((i & ~0x7F) == 0) 
     return i; 

    int num = i & 0x7F; 

    // We can't handle length longer than 4 bytes 
    if (i >= 0xFF || num > 4) 
     throw new IOException("Invalid DER: length field too big (" //$NON-NLS-1$ 
      + i + ")"); //$NON-NLS-1$ 

    byte[] bytes = new byte[num];  
    int n = in.read(bytes); 
    if (n < num) 
     throw new IOException("Invalid DER: length too short"); //$NON-NLS-1$ 

    return new BigInteger(1, bytes).intValue(); 
    } 

} 


/** 
* An ASN.1 TLV. The object is not parsed. It can 
* only handle integers and strings. 
* 
* @author zhang 
* 
*/ 
class Asn1Object { 

    protected final int type; 
    protected final int length; 
    protected final byte[] value; 
    protected final int tag; 

    /** 
    * Construct a ASN.1 TLV. The TLV could be either a 
    * constructed or primitive entity. 
    * 
    * <p/>The first byte in DER encoding is made of following fields, 
    * <pre> 
    *------------------------------------------------- 
    *|Bit 8|Bit 7|Bit 6|Bit 5|Bit 4|Bit 3|Bit 2|Bit 1| 
    *------------------------------------------------- 
    *| Class | CF |  +  Type    | 
    *------------------------------------------------- 
    * </pre> 
    * <ul> 
    * <li>Class: Universal, Application, Context or Private 
    * <li>CF: Constructed flag. If 1, the field is constructed. 
    * <li>Type: This is actually called tag in ASN.1. It 
    * indicates data type (Integer, String) or a construct 
    * (sequence, choice, set). 
    * </ul> 
    * 
    * @param tag Tag or Identifier 
    * @param length Length of the field 
    * @param value Encoded octet string for the field. 
    */ 
    public Asn1Object(int tag, int length, byte[] value) { 
    this.tag = tag; 
    this.type = tag & 0x1F; 
    this.length = length; 
    this.value = value; 
    } 

    public int getType() { 
    return type; 
    } 

    public int getLength() { 
    return length; 
    } 

    public byte[] getValue() { 
    return value; 
    } 

    public boolean isConstructed() { 
    return (tag & DerParser.CONSTRUCTED) == DerParser.CONSTRUCTED; 
    } 

    /** 
    * For constructed field, return a parser for its content. 
    * 
    * @return A parser for the construct. 
    * @throws IOException 
    */ 
    public DerParser getParser() throws IOException { 
    if (!isConstructed()) 
     throw new IOException("Invalid DER: can't parse primitive entity"); //$NON-NLS-1$ 

    return new DerParser(value); 
    } 

    /** 
    * Get the value as integer 
    * 
    * @return BigInteger 
    * @throws IOException 
    */ 
    public BigInteger getInteger() throws IOException { 
     if (type != DerParser.INTEGER) 
     throw new IOException("Invalid DER: object is not integer"); //$NON-NLS-1$ 

     return new BigInteger(value); 
    } 

    /** 
    * Get value as string. Most strings are treated 
    * as Latin-1. 
    * 
    * @return Java string 
    * @throws IOException 
    */ 
    public String getString() throws IOException { 

    String encoding; 

    switch (type) { 

    // Not all are Latin-1 but it's the closest thing 
    case DerParser.NUMERIC_STRING: 
    case DerParser.PRINTABLE_STRING: 
    case DerParser.VIDEOTEX_STRING: 
    case DerParser.IA5_STRING: 
    case DerParser.GRAPHIC_STRING: 
    case DerParser.ISO646_STRING: 
    case DerParser.GENERAL_STRING: 
     encoding = "ISO-8859-1"; //$NON-NLS-1$ 
     break; 

    case DerParser.BMP_STRING: 
     encoding = "UTF-16BE"; //$NON-NLS-1$ 
     break; 

    case DerParser.UTF8_STRING: 
     encoding = "UTF-8"; //$NON-NLS-1$ 
     break; 

    case DerParser.UNIVERSAL_STRING: 
     throw new IOException("Invalid DER: can't handle UCS-4 string"); //$NON-NLS-1$ 

    default: 
     throw new IOException("Invalid DER: object is not a string"); //$NON-NLS-1$ 
    } 

    return new String(value, encoding); 
    } 
} 
1

provare questo:

java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
+0

Non è più necessario che aggiungere il provider? Non dovrebbe essere fatto qualcosa anche con 'KeyFactory'? – jww

+0

Volevo solo dare i miei due centesimi che sto usando l'API Netty e Bouncy Castle insieme e stavo avendo tonnellate di eccezioni SSL su questo e quello, compreso il problema che l'OP stava avendo. Ero dubbioso ma l'aggiunta del codice precedente alla mia inizializzazione SSL ha effettivamente risolto tutti i miei problemi SSL. Sono sbalordito ha funzionato. –