簡體   English   中英

從文件中讀取公共密鑰

[英]Read public key from file

我正在嘗試用我的Java程序驗證文件。 我不知道我在做什么錯,我發現的所有解決方案都行不通。 這是我的代碼:

public boolean pruefeSignatur(File file, File signatur, File publicKey) {
    boolean verifies = false;
    try {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        // encode public key bytes
        FileInputStream keyfis = new FileInputStream(publicKey);
        byte [] encKey = new byte[keyfis.available()];
        keyfis.read(encKey);
        keyfis.close();
        // key specification
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
        // conversion
        KeyFactory keyFactory = KeyFactory.getInstance(pubKeySpec.getFormat());
        // generate publicKey
        PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
        // input signature bytes
        FileInputStream sigfis = new FileInputStream(signatur);
        byte[] sigToVerify = new byte[sigfis.available()];
        sigfis.read(sigToVerify);
        sigfis.close();
        // initialize the signature
        Signature sig = Signature.getInstance("RSA");
        sig.initVerify(pubKey);
        // supply signature object with the data to be verified
        FileInputStream datafis = new FileInputStream(file);
        BufferedInputStream bufin = new BufferedInputStream(datafis);
        byte[] buffer = new byte[1024];
        int len;
        while(bufin.available() != 0) {
            len = bufin.read(buffer);
            sig.update(buffer, 0, len);
        }
        bufin.close();
        //verify signature
        verifies = sig.verify(sigToVerify);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return verifies;
}

有了這段代碼,我得到了異常:java.security.spec.InvalidKeySpecException:java.lang.ClassCastException:org.bouncycastle.asn1.DERUnknownTag無法轉換為org.bouncycastle.asn1.ASN1Object

例如,當我使用Base64時:

        Base64 decoder = new Base64();
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(decoder.decode(encKey));

我收到異常:java.security.spec.InvalidKeySpecException:java.io.IOException:意外的內容結束標記

我發現的另一個解決方案是將其更改為:

        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
        // conversion
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

但是然后我得到了異常:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:無效的密鑰格式

我用Gpg4win和Kleopatra做鑰匙。

編輯:現在我沒有收到錯誤,但是函數總是返回false。 所以我不確定一切是否正確。

public boolean pruefeSignatur(File file, File signaturFile, File publicKeyFile) throws IOException {
    boolean verifies = false;
    FileInputStream keyfis = null;
    DataInputStream keydis = null;
    FileInputStream sigfis = null;
    DataInputStream sigdis = null;
    FileInputStream datafis = null;
    DataInputStream datadis = null;
    try {
        // add provider
        Security.addProvider(new BouncyCastleProvider());

        // encode public key bytes
        keyfis = new FileInputStream(publicKeyFile);
        keydis = new DataInputStream(keyfis);
        byte[] keyBytes = new byte[(int) publicKeyFile.length()];
        keydis.readFully(keyBytes);
        keyfis.close();
        keydis.close();

        // key specification
        String modulusBase64 = new String(keyBytes);
        Base64 b64 = new Base64();
        String exponentBase64 = "65337"; //festgelegte Zahl http://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(1, b64.decode(modulusBase64)), new BigInteger(1, b64.decode(exponentBase64)));

        // conversion
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        // generate publicKey
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);

        // read signature
        sigfis = new FileInputStream(signaturFile);
        sigdis = new DataInputStream(sigfis);
        byte[] sigBytes = new byte[(int) signaturFile.length()];
        sigdis.readFully(sigBytes);
        sigfis.close();
        sigdis.close();

        // initialize the signature
        Signature sig = Signature.getInstance("RSA");
        sig.initVerify(publicKey);

        // supply signature object with the data to be verified
        datafis = new FileInputStream(file);
        datadis = new DataInputStream(datafis);
        byte[] dataBytes = new byte[(int) file.length()];
        datadis.readFully(dataBytes);
        /*
        int len;
        while(datadis.available() != 0) {
            len = datadis.read(dataBytes);
            sig.update(dataBytes, 0, len);
        }
        */
        datadis.close();
        datafis.close();
        sig.update(dataBytes);

        //verify signature
        verifies = sig.verify(sigBytes);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (keyfis != null) {
            keyfis.close();
        }
        if (keydis != null) {
            keydis.close();
        }
        if (sigfis != null) {
            sigfis.close();
        }
        if (sigdis != null) {
            sigdis.close();
        }
        if (datafis != null) {
            datafis.close();
        }
        if (datadis != null) {
            datadis.close();
        }
    }
    return verifies;
}

最后我有一個解決方案:

    InputStream inSig = PGPUtil.getDecoderStream(new FileInputStream(signaturFile));
    //ArmoredInputStream inSig = new ArmoredInputStream(new FileInputStream(signaturFile));
    JcaPGPObjectFactory objFactory = new JcaPGPObjectFactory(inSig);
    PGPSignatureList signatureList = (PGPSignatureList) objFactory.nextObject();
    PGPSignature signature = signatureList.get(0);

    InputStream keyIn = PGPUtil.getDecoderStream(new FileInputStream(publicKeyFile));
    //ArmoredInputStream keyIn = new ArmoredInputStream(new FileInputStream(publicKeyFile));
    JcaPGPPublicKeyRingCollection pgpRing = new JcaPGPPublicKeyRingCollection(keyIn);
    PGPPublicKey publicKey = pgpRing.getPublicKey(signature.getKeyID());

    byte[] bytePublicKeyFingerprint = publicKey.getFingerprint();
    char[] publicKeyFingerprintHexArray = org.apache.commons.codec.binary.Hex.encodeHex(bytePublicKeyFingerprint);
    String publicKeyFingerprintHex = new String(publicKeyFingerprintHexArray);

    signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);

    FileInputStream in = new FileInputStream(file);
    byte[] byteData = new byte[(int) file.length()];
    in.read(byteData);
    in.close();
    signature.update(byteData);

    if (signature.verify() && publicKeyFingerprintHex.equals(fingerprint)) {
        return true;
    } else {
        return false;
    }

暫無
暫無

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

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