java.security.InvalidKeyException: IOException : algid parse error, not a sequence

3943 ワード

に質問
JAvaはopensslで生成したPEM形式の秘密鍵ファイルを使用してfactory.generatePrivateを呼び出すタイミングが間違っています
java.security.InvalidKeyException: IOException : algid parse error, not a sequence
 
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import org.junit.Test;
public class keyTest {

    @Test
    public void parseDERFromPEM() throws InvalidKeySpecException, NoSuchAlgorithmException {
        String privatekey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDYPducgwi8cvAc4Uw2AMEJzb4j3gRO+dGmb69NoJ8SFWruaFSND1sV6/Gs8ssPaG9+GUMmD2DMhzRxeW5TS1ycPxL2L7B7jBGys1j+0z7VUjCnY3+2M42qVs53RqyHqH48Gc1I+yCuDYTIq+OnLRuRidUBLj1qcfxziLZPSqjkHOcDCxmglTKghh9QbQYIdqGVnR5whqFXXc3TrGGIOvQM/y/ke2IDE45xMkYfvNRwpor4jYbAvx0XlXkmjwP1zC8g7uWg8pdQA5fTQOfq5GTWm9VJQgDZsFsXypTURcvhobxKn+zMtZ1TboR6ooRpjXgLQ5CpgQbRYFeYQQWrvzgNAgMBAAECggEAHuWXv2EpmmOB016NmRm6e0AebtmGHBKt1e4XSiwtDlRpFu9pRU5wYU15FpEKWoU9iPLrGUERP6gB4kTLcrNN5DVO7EYcHUsCLFpb2O0uCSTZNtGMqefr0e7dSUWb2TZF8yhsoIThQn1D/7gvqu9TBRSAjs6gj9kBjTB3fBTa1NzZBMG/RJwP7UreGhhkDHEj464ywFjGszkKJrCUqJCXpdGJaV0J76OSk5lQVmNCCyWhaBZF0z2SSsIeRwckPyGULJfkcSdM5DqzHEDup7b1sTSn+zW+Lv6O9kvQKuxjT6a81ezG/k0Kg0U/XK/geUani10sUq3gM1V7oLsxa+8CgQKBgQD25hrc6x7o2OznlTYvhGPFtzFZ/Dcz+r46jhTa2L+aeHPrEU/UMx2bQoNAs6S2RxQ540SsFaMn1sk9mSdBtmFP0qnYIvcARM2CHhyu6qEU7AiF2AKvq6OU9sPdMFZNtK3D5szo1JmGdzUr2ZwiCKf0nkRop3+VKyKZeIzMHSRZJQKBgQDgNnOuX6L/7ZPgOJODKibAnfQtCZe8pOoCKkmu5ZQO7yq6vVdsqMU59Sp8FJ8M0Yy5eF50RVD0CovnUVSkOOpmML34k6Rg0QusUWiZbzbOp3oEUbS56/qtSDV0M/DaeFoYMbITFdp0Pap05ih4p8hLDYKcCZmyWr1/ZyUhMdwyyQKBgBq11h4kSZnDLg33tH77gZe4M9yaTpaO/9lx2Yu7ey8I7PF3U/2O8hsD3RM43A7kLan9jkZXqOj8cZT6ZqbTRj/OeJVrYvFigCEdhNjfhUGwL1PbhJ7goLfS4mmhexS5ATt6Upy1s046w0PVLPD5osHyBVCVHlZS7lFQG1tRo8cJAoGANxWJpCyA2kmfC/Y6X34qmSX1SF9T9Re7Gh8TjTGAB49AuzIrWVm5YrzV3Dggv0B4R1TIN96TvfEdYA4+Mj59b+/HrFtxhgu1x3cUsKV/HJROyOLd+NN9+baE03CzWqk40TrcWg4DZo2D5EZraQEnlzDRhs5hAU2DwtovaBFc3OkCgYEAx9JNKihuzCizby/ywDlU9yswkw1XdyAKNSl+obAqNvSqcRgK2LuYmhLrXbmqIEtzDBgiWMcfAvsjSzTVgLhM3zV2QLnMaKbKgIpy0f4MVrLigB74PJqlJER4gav3u7v936SXohiz9yEubj/+5EGGFLoDp0dfrERqLg6R9FhpIFQ=";
        byte[] keyBytes = Base64.getDecoder().decode(privatekey);
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory factory = KeyFactory.getInstance("RSA");
        RSAPrivateKey priKey = (RSAPrivateKey)factory.generatePrivate(spec);
    }
}

エラーの原因 :転送された秘密鍵列privateKeyフォーマットはPKC 8フォーマットではなく、誤ったprivateKeyはopensslによって生成された秘密鍵であり、ファイルから秘密鍵ヘッダ(----BEGIN RSA PRIVATE KEY---)と秘密鍵テール(----END RSA PRIVATE KEY---)を削除して得られる
注意:
フォーマット要件に適合する秘密鍵ファイルは、---BEGIN PRIVATE KEY---で始まる
フォーマット要件を満たしていない秘密鍵ファイルは、---BEGIN RSA PRIVATE KEY---で始まる
解決策は次の3つです.
一、既存秘密鍵のフォーマット変換
例えば、以下のopensslコマンドを用いて生成される秘密鍵ファイルフォーマットはpkcs 1である
openssl genrsa -out private.key 2048

次のopensslコマンドを使用して、PKCS 1形式のprivate.keyファイルをPKCS 8形式の新しい秘密鍵ファイルpkcs 8 Private.keyに変換できます. 
openssl pkcs8 -topk8 -inform PEM -in private.key -outform pem -nocrypt -out pkcs8Private.key 

pkcs 8からpkcs 1コマンドに変換:
openssl pkcs8 -in pkcs8.pem -nocrypt -out pri_key.pem

 
二、直接PKC 8形式の秘密鍵を生成する
秘密鍵生成コマンド
openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out client.key

 
三、javaはBouncyCastleライブラリのPEMReaderを用いてPEM形式の秘密鍵を読み取る
reader = new PEMReader(new InputStreamReader(new ByteArrayInputStream(keyBytes)));
PrivateKey key = (PrivateKey)reader.readObject();

bouncycastleライブラリリンク
参照リンク:java pem形式SSL証明書を使用してhttpsを要求
https://blog.csdn.net/tuanyuanmian/article/details/88607621
 
 
解決策の主な参考源:
https://stackoverflow.com/questions/6559272/algid-parse-error-not-a-sequence/46988448