J'écris un projet client/serveur qui nécessite une signature. J'utilise base64(hmac-sha1(key, data))
pour générer une signature. Mais je suis arrivé différentes signatures entre code python et code c objectif:Pourquoi mon code python et objectif-c obtient-il un résultat hmac-sha1 différent?
get_signature('KEY', 'TEXT') //python get 'dAOnR2oXWP9xa4vUBdDvVXTpzQo='
[self hmacsha1:@"KEY" @"TEXT"] //obj-c get '7FH0NG0Ou4nb5luKUyjfrdWunos='
Non seulement les valeurs de base64 sont différentes, le HMAC-SHA1 valeurs sont différentes aussi. J'essaie de travailler avec mon ami pendant quelques heures, je ne comprends toujours pas. Où est le problème de mon code?
Mon code python:
import hmac
import hashlib
import base64
def get_signature(key, msg):
return base64.b64encode(hmac.new(key, msg, hashlib.sha1).digest())
Mon ami de code c objectif (copie de Objective-C sample code for HMAC-SHA1):
(NSString *)hmac_sha1:(NSString *)key text:(NSString *)text{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [text cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [GTMBase64 stringByEncodingData:HMAC];
return hash;
}
RESOLU: Merci pour tout le monde ci-dessous. Mais je ne dois vous dire que la vraie raison est que je tapais « TE S T » dans mon python IDE en typé « TE X T » dans ce post: P
Pour ne pas perdre votre temps, J'ai fait quelques tests et a obtenu une solution plus agréable, la base de vos réponses:
print get_signature('KEY', 'TEXT')
# 7FH0NG0Ou4nb5luKUyjfrdWunos=
print get_signature(bytearray('KEY'), bytearray('TEXT'))
# 7FH0NG0Ou4nb5luKUyjfrdWunos=
print get_signature('KEY', u'你好'.encode('utf-8')) # best solution, i think!
# PxEm7Oibj7ijZ55ko7V3isSkD1Q=
print get_signature('KEY', bytearray(u'你好'))
# TypeError: unicode argument without an encoding
print get_signature('KEY', u'你好')
# UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
print get_signature(u'KEY', 'TEXT')
# TypeError: character mapping must return integer, None or unicode
print get_signature(b'KEY', b'TEXT')
# 7FH0NG0Ou4nb5luKUyjfrdWunos=
Conclusion:
- Le message à la signature doit être codé à chaîne utf-8 avec les deux côtés.
- (Merci à DJV) En python 3, les chaînes sont toutes unicode, elles doivent donc être utilisées avec 'b', ou bytearray (grâce à Burhan Khalid), ou encodées en chaîne utf-8.
Selon [ce site] (http://hash.online-convert.com/sha1-generator), votre ami est le bon – dmg
Eh bien, c'était bizarre, votre code produit '7FH0NG0Ou4nb5luKUyjfrdWunos =' aussi bien sur Python 2. Êtes-vous en utilisant Python 3? – dmg
Ok, dernier suivi. Si vous utilisez Python 3, vous devriez l'appeler comme 'get_signature (b'KEY ', b'TEXT')' comme 'string's sont' unicode' – dmg