从PFX获取签名和认证路径

时间:2014-06-27 04:29:14

标签: java certificate digital-signature pfx

我有一条像

这样的SOAP消息
<soapenv:Envelope
    xmlns:soapenv = "http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:v = "http://www.something.com">
    <soapenv:Header/>
    <soapenv:Body>
        <v:Auth>
            <v:userID>xxxxxxxxxx</v:userID>
            <v:password>xxxxxxxxxx</v:password>
            <v:certChain>xxxxxxxxxx</v:certChain>
            <v:signature>xxxxxxxxxx</v:signature>
        </v:Auth>
    </soapenv:Body>
</soapenv:Envelope>

从WSDL生成java源代码后,对于Auth,我正在设置这样的值。 (以下所有4个字段都是字符串数据类型)

Auth authInfo = new Auth();
authInfo.setUserID(userId);
authInfo.setPassword(password);
authInfo.setCertChain("");
authInfo.setSignature("");

以下是我获得签名,摘要值,证书链的一段代码。但是当我填充值并提交SOAP消息时,我得到了数字签名无效错误。但我确认签名有效。

提取详细信息的代码:

我面临从pfx文件获取认证路径和签名的问题。你能分享得到它们的代码,我有以下代码来获取它们。当我使用通过以下代码获得的签名和证书路径时,我总是获得无效的数字签名。

public void getCertificateDetails(){
    String aliasName="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // not posted here

    try{ 

         char[] passwd = KEY_STORE_PASSWORD.toCharArray();          

         keyStore = KeyStore.getInstance("PKCS12","SunJSSE");


         FileInputStream fis = new FileInputStream("path to pfx file");
         keyStore.load(fis, passwd);

         fis.close();

         Enumeration aliases;


         Certificate[] cc =  keyStore.getCertificateChain(aliasName);
         X509Certificate certificate1 = (X509Certificate) cc[0];

         System.out.println("signo algo:"+certificate1.getSigAlgName()); // get the value as SHA256withRSA

         PrivateKey pKey = (PrivateKey)keyStore.getKey("xxxxxxxxxxxxxxxxxxxxxxxxx", passwd);



         keyStore.getCertificate(aliasName);
         X509Certificate[] result = new X509Certificate[2];

         X509Certificate certificate2 = (X509Certificate)keyStore.getCertificate(aliasName);
         byte[] sig = certificate2.getSignature();



         certChain=keyStore.getCertificateChain(aliasName);
         algorithm=keyStore.getKey(aliasName, passwd).getAlgorithm();
         certificate=keyStore.getCertificate(aliasName);

         System.out.println("public key:"+certificate.getPublicKey().getEncoded());
         PrivateKey myPrivateKey = (PrivateKey)keyStore.getKey(aliasName, passwd);
         xCert = (X509Certificate)certificate;


         keyStore.getCertificate(aliasName).verify( keyStore.getCertificate( aliasName ).getPublicKey());

         x509Content.add(xCert.getSubjectX500Principal().getName());
         x509Content.add(xCert);
    } 
    catch(Exception ex)
    {
        ex.printStackTrace();
    }

 }

 // Get certificate chain
 public Certificate[] getCertificateChain()
 {
     return certChain;
 }

 public String getAlgorithm()
 {

     return algorithm;
 }
 public Certificate getCertificate()
 {
     return certificate;
 }
 public signature getX509Signature()
 {

     return xCert.getSignature();
 }

}

用于取消摘要值的代码

  public String hexify (byte bytes[]) 
  {

      char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', 
            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

      StringBuffer buf = new StringBuffer(bytes.length * 2);

      for (int i = 0; i < bytes.length; ++i) {
          buf.append(hexDigits[(bytes[i] & 0xf0) >> 4]);
          buf.append(hexDigits[bytes[i] & 0x0f]);
      }

      return buf.toString();
  }

从签名中获取摘要值

public String getThumbPrint(X509Certificate cert) throws NoSuchAlgorithmException, CertificateEncodingException 
{
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    byte[] der = cert.getSignature();

    md.update(der);


    byte[] digest = md.digest();

    digest=md.digest(digest);


    return hexify(digest);

}

0 个答案:

没有答案