Я пишу проект клиент/сервер, которому нужна подпись. Я использую base64(hmac-sha1(key, data))
для создания подписи. Но я получил разные подписи между питона кода и Objective-C код:Почему мой код python и object-c получает другой результат hmac-sha1?
get_signature('KEY', 'TEXT') //python get 'dAOnR2oXWP9xa4vUBdDvVXTpzQo='
[self hmacsha1:@"KEY" @"TEXT"] //obj-c get '7FH0NG0Ou4nb5luKUyjfrdWunos='
не только значения base64 различны, HMAC-SHA1 дайджест значения отличаются слишком. Я пытаюсь разобраться с моим другом в течение нескольких часов, но не понимаю. Где проблема моего кода?
Мой питон код:
import hmac
import hashlib
import base64
def get_signature(key, msg):
return base64.b64encode(hmac.new(key, msg, hashlib.sha1).digest())
моего друга Objective-C код (копия 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;
}
РЕШИТЬ: Спасибо всем ниже. Но я не должен вам сказать, что реальная причина я напечатал «TE S T» в моем питона IDE, а напечатал «TE X T» в этом посте: P
Для не тратить свое время, Я сделал несколько тестов и получили более хорошее решение, на базе ваших ответов:
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=
Вывод:
- сообщение будет подпись должна быть закодированы в UTF-8 строку с обеих сторон.
- (Спасибо DJV) В python 3 строки все unicode, поэтому они должны использоваться с 'b' или bytearray (спасибо Burhan Khalid) или закодированы в строку utf-8.
По [этот сайт] (http://hash.online-convert.com/sha1-generator), ваш друг правильный – dmg
Ну, это было странно, ваш код создает '7FH0NG0Ou4nb5luKUyjfrdWunos =' также на Python 2. Вы используя Python 3? – dmg
ОК, окончательный контроль. Если вы используете Python 3, вы должны называть его как 'get_signature (b'KEY ', b'TEXT')' as 'string' '' unicode' – dmg