HMACSHA1을 손으로 구현하려고합니다. 서비스 제공자 또는 지원 티켓 (SOAP 호출, 따라서 XML 콘텐츠)에 대해 잘못된 HMAC를 계산했는지 확인해야합니다.Manual HMACSHA1 계산이 openssl 결과와 다릅니다.
문제는 HMAC의 NIST 사양을 고수하고 Hands와 OpenSSL HMAC 기능을 사용할 때 다른 결과를 얻는 것입니다.
다음 코드를 인쇄 :
B92674DCBA96F2DA93F7043071B931F5F2583FBD
4303E965D88D288C9AC594CE6C5E6AFF27D40B2D
하려면 openssl에 의한 결과는 우리가 우리의 응용 프로그램에서 얻을 동일하지만
- 그래서 나는 내 결과가 잘못되었다고, OpenSSL이 너무 일반적으로 사용되는 기준으로, 가정 - 하지만 내 오류는 어디 있습니까?#include <stdio.h>
#include <stdlib.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <string.h>
#define byte unsigned char
#define IPAD 0x36
#define OPAD 0x5c
#define DIGESTSIZE 20
int main() {
byte *derivedKey = (byte[DIGESTSIZE]) {0x42,0xA9,0x78,0x90,0xFC,0xE5,0x16,0x8E,0x58,0x12,0x2F,0xF1,0xBA,0x32,0x5F,0x09,0x88,0x94,0x02,0x91};
byte *content = "<ds:SignedInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"><ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"><ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"soap\"></ec:InclusiveNamespaces></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#hmac-sha1\"></ds:SignatureMethod><ds:Reference URI=\"#TS-B183A13FEB0189143115136776276601\"><ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"><ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"wsse soap\"></ec:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"></ds:DigestMethod><ds:DigestValue>rXJdGuDqoRrUJxuGiA1eyAozifk=</ds:DigestValue></ds:Reference></ds:SignedInfo>";
byte *oPadKey = malloc(DIGESTSIZE);
byte *iPadKey = malloc(DIGESTSIZE);
int i;
for(i=0;i<DIGESTSIZE;i++){
iPadKey[i]=derivedKey[i]^IPAD;
oPadKey[i]=derivedKey[i]^OPAD;
}
byte *rOpInput= malloc(strlen(content)+DIGESTSIZE);
//concat iPad and content
memcpy(rOpInput, iPadKey, DIGESTSIZE);
memcpy(rOpInput+DIGESTSIZE,content,strlen(content));
//SHA1 (iPad||content) gives the rightmost 20 bytes of the final SHA1 Input
byte *rOp=malloc(DIGESTSIZE); // H(iPad||content)
SHA1(rOpInput,strlen(content)+DIGESTSIZE,rOp);
free(rOpInput);
byte *finalInput = malloc(2*DIGESTSIZE); //oPad||H(iPad||content)
//concat oPad and H(ipad||content)
memcpy(finalInput, oPadKey,DIGESTSIZE);
memcpy(finalInput+DIGESTSIZE,rOp,DIGESTSIZE);
free(rOp);
free(oPadKey);
free(iPadKey);
//SHA1(oPad||H(iPad||content))
byte *hmac = malloc(DIGESTSIZE);
SHA1(finalInput,40,hmac);
free(finalInput);
//print calculated HMAC as HEX
for(i=0;i<DIGESTSIZE;i++){
printf("%02X", (hmac[i] & 0xFF));
}
printf("\n");
//verify with openssl HMAC
byte *result = HMAC(EVP_sha1(), derivedKey, DIGESTSIZE, content, strlen(content), NULL, NULL);
for(i=0;i<DIGESTSIZE;i++){
printf("%02X", (result[i] & 0xFF));
}
printf("\n");
return 0;
}
아아, 24 바이트 길이이므로 키를 해시 할 필요가 없습니다. – billdoor
그래, 그게 내가 –
을 읽는 방법이다. 자바 프레임 워크 apache cxf/wss4j는 HMAC를 계산하기 전에 hmacsha1에서 20 바이트까지 사용하는 키를 "잘라내"않는다. 단지 마지막 4 바이트를 떨어 뜨렸다. 어쨌든 이것은 틀린가? 원래 키는 24 바이트입니다. – billdoor