2011-12-21 25 views
1

x509証明書で署名されたS/MIMEメッセージの検証にはいくつか問題があります。これは私のコードです:x509証明書を使用したS/MIME検証

public class verifyMsg { 

private static void verify(SMIMESignedParser s) throws Exception { 

    Security.addProvider(new BouncyCastleProvider()); 
    System.out.println("wbilem"); 
    CertStore certs = s.getCertificatesAndCRLs("Collection", "BC"); 

    SignerInformationStore signers = s.getSignerInfos(); 
    Collection c = signers.getSigners(); 
    Iterator it = c.iterator(); 

    while (it.hasNext()) { 
     File f = new File("signature.crt"); 
     FileInputStream fis = new FileInputStream(f); 
     DataInputStream dis = new DataInputStream(fis); 
     byte[] keyBytes = new byte[(int) f.length()]; 
     dis.readFully(keyBytes); 
     dis.close(); 
     fis.close(); 
     SignerInformation signer = (SignerInformation) it.next(); 
     Collection certCollection = certs.getCertificates(signer.getSID()); 
     Iterator certIt = certCollection.iterator(); 
     FileInputStream fr = new FileInputStream("signature.crt"); 
     CertificateFactory cf = CertificateFactory.getInstance("X509"); 
     X509Certificate cert = (X509Certificate) cf.generateCertificate(fr); 


     if (signer.verify(cert, "BC")) { //problem is there... 
      System.out.println("signature verified"); 
     } else { 
      System.out.println("signature failed!"); 
     } 

    } 
} 

public static void main(String[] args) throws Exception { 
    Properties props = System.getProperties(); 
    Session session = Session.getDefaultInstance(props, null); 

    try { 
     FileInputStream fr = new FileInputStream("signature.crt"); 
     CertificateFactory cf = CertificateFactory.getInstance("X509"); 
     X509Certificate c = (X509Certificate) cf.generateCertificate(fr); 
     System.out.println("Read in the following certificate:"); 
     System.out.println("\tCertificate for: " + c.getSubjectDN()); 
     System.out.println("\tCertificate issued by: " + c.getIssuerDN()); 
     System.out.println("\tThe certificate is valid from " + c.getNotBefore() + " to " + c.getNotAfter()); 
     System.out.println("\tCertificate SN# " + c.getSerialNumber()); 
     System.out.println("\tGenerated with " + c.getSigAlgName()); 
     System.out.println(c.getPublicKey()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    try { 
     MimeMessage msg = new MimeMessage(session, new SharedFileInputStream("G:\\MIME.txt")); 
     if (msg.isMimeType("multipart/signed")) { 

      SMIMESignedParser s = new SMIMESignedParser((MimeMultipart) msg.getContent()); 
      System.out.println("Status:"); 
      verify(s); 
     } else if (msg.isMimeType("application/pkcs7-mime")) { 

      // in this case the content is wrapped in the signature block. 
      // 
      SMIMESignedParser s = new SMIMESignedParser(msg); 
      System.out.println("Status1:"); 
      verify(s); 
     } else { 
      System.err.println("Not a signed message!"); 
     } 

    } catch (MessagingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (CMSException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

}

、私はこの例外に問題があります。

CMSSignerDigestMismatchException:メッセージダイジェスト属性値が計算値と一致していませんが。私は何が間違っているのか分かりません。私はjdk 1.4.2を使用します。

答えて

1

私は、問題がメッセージであることを知りました。バイト配列を文字列に変換し、次にこの文字列を入力ストリームに変換しました。今私は変換せずに入力ストリームのバイト配列に与えるとすべてが大丈夫です

+0

コードで行った正確な変更私は同じ問題に直面しています。あなたのコードで変更したコードスニペットを参考にしてください。 – Swapnil

0

私はこの問題を解決しました.S/MIMEとS/MIMEの標準に従って私たちはMIMEバージョン、コンテンツタイプが必要です。 ..etcとヘッダーは空白行で署名するメッセージから分離されています。メッセージのタイプが「text/plain」のときは、メッセージにヘッダーを追加することはほとんどありません。しかし、S/MIMEを使用してS/MIME標準ヘッダーを検索し、ダイジェストでmiss machのような問題が発生するデータに署名します。

署名する前にメッセージに次のヘッダーを追加してください。 MIME-Version:1.0 Content-Type:text/plain;

メッセージの前に空白行を1つだけ追加してください。

上記のアプローチは問題なく機能しています。

関連する問題