【发布时间】:2012-11-16 11:51:06
【问题描述】:
以下是作为数字签名处理程序一部分的代码
final String NAMESPACEURI_WSSECURITY_WSU=
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
final String NAMESPACEURI_WSSECURITY_WSSE =
"http://docs.oasisopen.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
1.0.xsd";
final String NAMESPACEURI_XMLSIGNATURE_DS = "http://www.w3.org/2000/09/xmldsig#";
final String ATTRIBUTENAME_X509TOKEN =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile
-1.0#X509v3";
final String ENCODINGTYPE_BASE64 =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-
security-1.0#Base64Binary";
SOAPHeaderElement securityElement = header
.addHeaderElement(new QName(
NAMESPACEURI_WSSECURITY_WSSE, "Security",
"wsse"));
//securityElement.setMustUnderstand(true);
securityElement.addNamespaceDeclaration("wsu",
NAMESPACEURI_WSSECURITY_WSU);
securityElement.addNamespaceDeclaration("ds",
NAMESPACEURI_XMLSIGNATURE_DS);
SOAPBody body = envelope.getBody();
String bodyIdRef = "Id-1-BD-1";
body.addAttribute(new QName(NAMESPACEURI_WSSECURITY_WSU, "Id",
"wsu"), bodyIdRef);
// Prepare security token element
SOAPElement binarySecurityTokenElement = securityElement
.addChildElement("BinarySecurityToken", "wsse");
String tokenIdRef = "Id-1-TK-1";
binarySecurityTokenElement.addAttribute(new QName(
NAMESPACEURI_WSSECURITY_WSU, "Id", "wsu"), tokenIdRef);
binarySecurityTokenElement.addAttribute(new QName("ValueType"),
ATTRIBUTENAME_X509TOKEN);
binarySecurityTokenElement.addAttribute(new QName(
"EncodingType"), ENCODINGTYPE_BASE64);
// Open keystore and insert encoded certificate
KeyStore store = KeyStore.getInstance("PKCS12"); //default is "JKS"
store.load(new FileInputStream(new File(KEYSTORE_LOC)),
KEYSTORE_STOREPASS.toCharArray());
KEYSTORE_KEYALIAS = (String)store.aliases().nextElement();
Certificate certificate = store
.getCertificate(KEYSTORE_KEYALIAS);
binarySecurityTokenElement.addTextNode(new String(Base64Coder
.encode(certificate.getEncoded())));
// Prepare digest for Signature generation
XMLSignatureFactory signFactory = XMLSignatureFactory
.getInstance("DOM");
C14NMethodParameterSpec spec1 = null;
CanonicalizationMethod c14nMethod = signFactory
.newCanonicalizationMethod(
CanonicalizationMethod.EXCLUSIVE, spec1);
DigestMethod digestMethod = signFactory.newDigestMethod(
DigestMethod.SHA256, null);
String methodNS = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
SignatureMethod signMethod = signFactory.newSignatureMethod(
methodNS, null);
TransformParameterSpec spec2 = null;
Transform transform = signFactory.newTransform(
CanonicalizationMethod.EXCLUSIVE, spec2);
List<Transform> transformList = Collections
.singletonList(transform);
List<Reference> referenceList = new ArrayList<Reference>();
Reference reference1 = signFactory.newReference(
"#" + bodyIdRef, digestMethod, transformList, null,
null);
referenceList.add(reference1);
SignedInfo signInfo = signFactory.newSignedInfo(c14nMethod,
signMethod, referenceList);
// Get Private key
Key privateKey = store.getKey(KEYSTORE_KEYALIAS,
KEYSTORE_KEYPASSWORD.toCharArray());
// Create <SignatureValue>
DOMSignContext dsc = new DOMSignContext(privateKey,
securityElement);
dsc.setDefaultNamespacePrefix("ds");
XMLSignature signature = signFactory.newXMLSignature(signInfo,
null);
signature.sign(dsc);
// Prepare key info element
SOAPElement signatureElement = (SOAPElement) securityElement
.getLastChild();
SOAPElement keyInfoElement = signatureElement
.addChildElement(new QName(
NAMESPACEURI_XMLSIGNATURE_DS, "KeyInfo", "ds"));
SOAPElement
securityTokenReferenceElement = keyInfoElement.addChildElement(
"SecurityTokenReference", "wsse");
SOAPElement referenceElement = securityTokenReferenceElement
.addChildElement("Reference", "wsse");
referenceElement.setAttribute("URI", "#" + tokenIdRef);
referenceElement.setAttribute("ValueType",
ATTRIBUTENAME_X509TOKEN);
我为 SOAP 调用启用了日志记录,并提取了正在计算 SHA-256 格式摘要的字符串。我使用相同的字符串来计算 c 中的摘要。以下是计算该值的 C++ 代码。这两个值都不同。
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <string>
#define std::string String
String conString = "String from logs ";
unsigned char md[SHA256_DIGEST_LENGTH];
unsigned int size = 0;
EVP_Digest(conString.c_str(), conString.size(), md, &size, EVP_sha256(),
NULL);
这方面的任何帮助都会有所帮助。谢谢
【问题讨论】:
-
看起来 java 正在生成一个 X509 签名,这将是一个用 RSA 加密的哈希。还有一个似乎是 base64 编码,而另一个没有。
-
Java 代码不仅仅是计算一个 SHA256 —— 它是一个XML Digital Signature。这与试图生成简单 SHA256 摘要的 OpenSSL sn-p 非常不同。
-
我知道它首先对其进行规范化,然后计算 sha256 ,因为我正在从传递给摘要函数的日志中提取字符串,因此摘要应该是相同的。
-
org.jcp.xml.dsig.internal.DigesterOutputStream write FINER: Pre-digested input: Nov 28, 2012 7:51:24 PM org.jcp.xml.dsig.internal.DigesterOutputStream write FINER : schemas.xmlsoap.org/soap/envelope" xmlns:wsu="docs.oasis-open.orgwss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Id-1 -BD-1">c14n 字符串的其他部分 2012 年 11 月 28 日 7:51:24 PM org.jcp.xml.dsig.internal.dom.DOMReference 摘要 FINE: Reference object uri = #Id- 1-BD-1 2012 年 11 月 28 日 7:51:24 PM org.jcp.xml.dsig.internal.dom.DOMReference 摘要
标签: java c openssl digital-signature message-digest