2015-12-03 5 views
0

Я пытаюсь проверить файл с помощью моей 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; 
} 

ответ

0

Наконец у меня есть решение:

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; 
    } 
Смежные вопросы