簡體   English   中英

從文件中讀取公鑰或私鑰時如何修復“無效密鑰格式”?

[英]How to fix "invalid key format" while read public or private key from file?

我已經創建了公鑰和私鑰。 從 php 代碼生成的公鑰和私鑰:

<?php
    require __DIR__ . '/vendor/autoload.php';
    use phpseclib\Crypt\RSA;
    $rsa = new RSA();
    extract($rsa->createKey()); 
    $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);
    $rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_PKCS8);

    file_put_contents("privateKey.pem",$privatekey);
    file_put_contents("publicKey.pem", $publickey);

讀取這些鍵的java源代碼:

    import java.io.*;
    import java.security.*;
    import java.security.spec.*;

    public class PublicKeyReader {

    public static PublicKey get(String filename)
        throws Exception {

        File f = new File(filename);
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int)f.length()];
        dis.readFully(keyBytes);
        dis.close();

        X509EncodedKeySpec spec =
          new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
      }

   public static void main (String [] args) throws Exception {
    PublicKeyReader publicKeyReader = new PublicKeyReader();
    PublicKey publicKey = publicKeyReader.get("key/testPub.pem");
    System.out.println(publicKey);
   }
   }

它產生java.security.InvalidKeyException: invalid key format.

在這方面需要幫助。 提前致謝。

首先,正如評論中所指出的,沒有 PKCS#8 公鑰這樣的東西。 這意味着 PHP 庫不知道它在說什么。 相反,如果 neubert 是正確的,您似乎得到的是為 X.509 證書定義的結構,稱為X509EncodedKeySpec 在 Java 代碼中,您確實嘗試使用它來讀取公鑰。

但是,您忘記了X509EncodedKeySpec是一種二進制格式,在 ASN.1 DER 中指定。 您收到的是一個使用 ASCII 盔甲的 PEM 編碼密鑰。 換句話說,二進制文件已被編碼為 base64 並添加了頁眉和頁腳行。 這樣做是為了使其與文本界面兼容,例如郵件(隱私增強郵件或 PEM)。

所以你要做的就是移除盔甲。 您最好使用 PEM 閱讀器(例如 Bouncy Castle 提供的閱讀器)來執行此操作。

PemReader reader = new PemReader(new FileReader("spki.pem"));
PemObject readPemObject = reader.readPemObject();
String type = readPemObject.getType();
byte[] subjectPublicKey = readPemObject.getContent();

System.out.println(type);

X509EncodedKeySpec spec = new X509EncodedKeySpec(subjectPublicKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(spec);
System.out.println(pubKey);

哪個打印

PUBLIC KEY

其次是

Sun RSA public key, 1024 bits
  params: null
  modulus: 119445732379544598056145200053932732877863846799652384989588303737527328743970559883211146487286317168142202446955508902936035124709397221178664495721428029984726868375359168203283442617134197706515425366188396513684446494070223079865755643116690165578452542158755074958452695530623055205290232290667934914919
  public exponent: 65537

對於懷疑論者 - 嗨 neubert ;) - 這里是X.509 規范中 SubjectPublicKeyInfo 的定義:

SubjectPublicKeyInfo  ::=  SEQUENCE  {
     algorithm            AlgorithmIdentifier,
     subjectPublicKey     BIT STRING  }

其中subjectPublicKey包含 PKCS#1 格式的編碼公鑰 - 當然,在 RSA 公鑰的情況下。

是 neubert 密鑰的解碼版本,因此您可以進行比較。 Java 中解析的鍵是同一個鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM