openssl digest different in c compared to java

ぃ、小莉子 提交于 2019-12-24 08:58:34

问题


Following is the code which is part of the 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<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);

I enabled logging for SOAP calls and extracted the string for which digest in SHA-256 form is being calculated. I used the same string to calculate the digest in c. Following is the code in C++ to calculate that. Both the values come out different.

  #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);

Any help in this regard would be helpful. Thanks


回答1:


Very Strange but the following snippet to calculate the sha256 generates the correct hash that matches the java output.

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;
}

:)



来源:https://stackoverflow.com/questions/13608286/openssl-digest-different-in-c-compared-to-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!