我有一条像
这样的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);
}