代码之家  ›  专栏  ›  技术社区  ›  AJ.

如何从文件中加载RSA私钥

  •  56
  • AJ.  · 技术社区  · 14 年前

    我能够构建SAMLResponse,添加必要的断言等,但是当我尝试对对象签名时,我遇到了问题。以下是我当前代码的一个片段:

    String certPath = "mycert.pem";
    File pubCertFile = new File(certPath);
    BufferedInputStream bis = null;
    try {
        bis = new BufferedInputStream(new FileInputStream(pubCertFile));
    } catch(FileNotFoundException e) {
        throw new Exception("Could not locate certfile at '" + certPath + "'", e);
    }
    CertificateFactory certFact = null;
    Certificate cert = null;
    try {
        certFact = CertificateFactory.getInstance("X.509");
        cert = certFact.generateCertificate(bis);
    } catch(CertificateException e) {
        throw new Exception("Could not instantiate cert", e);
    }
    bis.close();
    ArrayList<Certificate> certs = new ArrayList<Certificate>();
    certs.add(cert);
    
    String keyPath = "mykey.pem";
    File privKeyFile = new File(keyPath);
    try {
        bis = new BufferedInputStream(new FileInputStream(privKeyFile));
    } catch(FileNotFoundException e) {
        throw new Exception("Could not locate keyfile at '" + keyPath + "'", e);
    }
    byte[] privKeyBytes = new byte[(int)privKeyFile.length()];
    bis.read(privKeyBytes);
    bis.close();
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    KeySpec ks = new PKCS8EncodedKeySpec(privKeyBytes);
    RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
    
    samlResponse.sign(Signature.getInstance("SHA1withRSA").toString(), privKey, certs);
    

    错误发生在倒数第二行。我在控制台中看到以下内容:

    java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
    

    虽然不是常规的或安全的,但是为了这个线程,我提供了我正在使用的公共证书和私钥。一旦问题解决了,我当然会重新创建新的

    aj@mmdev0:~/$ cat mykey.pem
    -----BEGIN RSA PRIVATE KEY-----
    MIICXgIBAAKBgQDnbcLSlDFaDMhalcmQgclTFobpkHQHJtxMVGRlbv7zknttAVbY
    1jzGjJ6HVupndzDxA9tbiMjQujmGlS/8g5IEbVsR9o6dmcmbvujtEZ2rHZ82tMYP
    VAt2IoS/W/q2Rr1cAZ/zTKEmh0ZZjzCZFueLfrYPm3am5JLcXgVtbKwybQIDAQAB
    AoGBAJ441oettYgBUUFNQv8/HGtn7Vjl38277cVptTH8DuZr8WJ3Fe8tmWONZBzX
    eW6/eIBuyJvuCo1ZpFa0zJfxQ/Ph6QlQwdN50GNfh9RzSS6lDdfy8BRhc27sypXS
    L6c5ljB6ql+pp3DdxFhJMOs3ZmBJdeyWe7uFrkngtnM1nxZBAkEA+1hbV1Q305wa
    u8YMF1SlNIAfgLJ7buD43SEXle0egz405PFG8f8yDmvROwDiRceILGVrRbInd7Cb
    dvJKr34WOQJBAOu2+reG44rNuiXeGX1MYg6TlWYyABm7PrTrhPZkedodOQB8p7zD
    AqtDSK7RnDCoThndPW6kdNAeB+kG4ug5XdUCQHRDU8UajNRSkj8nhjJIkj6twWS7
    qsMIR7Wp+An+7C1TWg5I2UNZg2MOVnNPnlseyAuZQjy0AvOnetJTk16IGWkCQQCL
    FUbOr8rnhgiGe4yywDVDwJVw3aPtiuyvOCEWeabkqkWOIf+fg7m5cFQcwxXUKBsd
    a8vp0yQSAQZN24Bb4i2ZAkEA8xGJFlFDY9HREWZnDey5STgbUeT1wYkyKcDsUrp1
    kR/3BliGqSIfje+mSKDIZqaP+gai/8bIABYAsDP/t6+cuA==
    -----END RSA PRIVATE KEY-----
    
    aj@mmdev0:~/$ cat mycert.pem
    -----BEGIN CERTIFICATE-----
    MIID7zCCA1igAwIBAgIJAKrURaAaD6ulMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
    VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xHDAa
    BgNVBAoTE0hvc3R3YXkgQ29ycG9yYXRpb24xITAfBgNVBAsTGFJlc2VhcmNoIGFu
    ZCBEZXZlbG9wbWVudDEYMBYGA1UEAxMPd3d3Lmhvc3R3YXkuY29tMR0wGwYJKoZI
    hvcNAQkBFg5hakBob3N0d2F5LmNvbTAeFw0xMDA3MTQwMjMyMDhaFw0xMTA3MTQw
    MjMyMDhaMIGsMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
    BAcTB0NoaWNhZ28xHDAaBgNVBAoTE0hvc3R3YXkgQ29ycG9yYXRpb24xITAfBgNV
    BAsTGFJlc2VhcmNoIGFuZCBEZXZlbG9wbWVudDEYMBYGA1UEAxMPd3d3Lmhvc3R3
    YXkuY29tMR0wGwYJKoZIhvcNAQkBFg5hakBob3N0d2F5LmNvbTCBnzANBgkqhkiG
    9w0BAQEFAAOBjQAwgYkCgYEA523C0pQxWgzIWpXJkIHJUxaG6ZB0BybcTFRkZW7+
    85J7bQFW2NY8xoyeh1bqZ3cw8QPbW4jI0Lo5hpUv/IOSBG1bEfaOnZnJm77o7RGd
    qx2fNrTGD1QLdiKEv1v6tka9XAGf80yhJodGWY8wmRbni362D5t2puSS3F4FbWys
    Mm0CAwEAAaOCARUwggERMB0GA1UdDgQWBBQI/4Inzs6OH5IquItuKhIrhPb24zCB
    4QYDVR0jBIHZMIHWgBQI/4Inzs6OH5IquItuKhIrhPb246GBsqSBrzCBrDELMAkG
    A1UEBhMCVVMxETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEwdDaGljYWdvMRww
    GgYDVQQKExNIb3N0d2F5IENvcnBvcmF0aW9uMSEwHwYDVQQLExhSZXNlYXJjaCBh
    bmQgRGV2ZWxvcG1lbnQxGDAWBgNVBAMTD3d3dy5ob3N0d2F5LmNvbTEdMBsGCSqG
    SIb3DQEJARYOYWpAaG9zdHdheS5jb22CCQCq1EWgGg+rpTAMBgNVHRMEBTADAQH/
    MA0GCSqGSIb3DQEBBQUAA4GBAA388zZp6UNryC/6o44hj7wTBQdzFFM5cs3B668A
    ylAnnal+J8RMIeCHoMF4S7yFQtYdOiWeScgw3c7KXrhJK1X7fU3I+eb1t3Yp1cTI
    htyzw14AoiICFalmlVgTCsn3+uh6AXP02PTkR8osdEpUOlWap4uzSKYNKc7tLOFd
    4CkM
    -----END CERTIFICATE-----
    

    谢谢!

    2 回复  |  直到 14 年前
        1
  •  73
  •   Alexander Kuznetsov    13 年前

    您需要使用以下命令将私钥转换为PKCS8格式:

    openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key_file  -nocrypt > pkcs8_key
    

    在此之后,您的java程序可以读取它。

        2
  •  20
  •   President James K. Polk    5 年前

    两件事。首先,必须对 mykey.pem 归档。第二,openssl私钥格式在 PKCS#1 RSAPrivateKey ASN.1结构。它与java的不兼容 PKCS8EncodedKeySpec ,这是基于 SubjectPublicKeyInfo ASN.1结构。如果你愿意使用 bouncycastle 你可以在库中使用几个类 bouncycastle provider bouncycastle PKIX 图书馆很快就能做到这一点。

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.security.KeyPair;
    import java.security.Security;
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openssl.PEMKeyPair;
    import org.bouncycastle.openssl.PEMParser;
    import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    
    // ...   
    
    String keyPath = "mykey.pem";
    BufferedReader br = new BufferedReader(new FileReader(keyPath));
    Security.addProvider(new BouncyCastleProvider());
    PEMParser pp = new PEMParser(br);
    PEMKeyPair pemKeyPair = (PEMKeyPair) pp.readObject();
    KeyPair kp = new JcaPEMKeyConverter().getKeyPair(pemKeyPair);
    pp.close();
    samlResponse.sign(Signature.getInstance("SHA1withRSA").toString(), kp.getPrivate(), certs);