与java相比,c中的openssl摘要不同

以下是代码,它是DigitalSigning Handler的一部分

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 transformList = Collections .singletonList(transform); List referenceList = new ArrayList(); 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  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  #include  #include  #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); 

在这方面的任何帮助都会有所帮助。 谢谢

非常奇怪,但以下片段计算sha256会生成与java输出匹配的正确哈希。

 String sha256(const String& string) { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, string.c_str(), string.size()); SHA256_Final(hash, &sha256); const char* digest = mcommons::util::base64(&hash[0], SHA256_DIGEST_LENGTH); String conString = digest; free((char*) digest); return conString; } 

🙂