Отличный результат HMAC для JAVA и iOS
Я пытаюсь сгенерировать HMAC на основе строкового значения и ключа
public static byte[] hmacSha1(String value, String key) throws NoSuchAlgorithmException, InvalidKeyException {
// some values hardcoded for simplicity of this code sample
key = "GET\\n?nodeList\\nThu, 10 Jul 2014 13:35:32 GMT\\nda39a3ee5e6b4b0d3255bfef95601890afd80709\\n";;
value = "6020834c535670ab1da86f7697241cb43ab6fb90";
final String type = "HmacSHA1";
final String charset = "ASCII";
byte[] keyBytes = new byte[0];
try {
keyBytes = key.getBytes(charset);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
SecretKeySpec secret = new SecretKeySpec(keyBytes, type);
Mac mac = Mac.getInstance(type);
mac.init(secret);
byte[] bytes = new byte[0];
try {
bytes = mac.doFinal(value.getBytes(charset));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.d(TAG, "bytes to hex: " + bytesToHex(bytes));
// result Android: 512B5CE2EA1CD71FF34C9DDB693F59288EF71B42
// iOS: 96f852a08d3ee255b77364a6bbd106be0dc0e44e
return bytes;
}
И результат Android (шестнадцатеричное значение) не совпадает с тем, в котором есть приложение для iOS (с использованием того же строкового значения и ключа).
(NSString *)HMAC_SHA1WithKeyData:(NSData* )key
{
const char * cData = [self cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, [key bytes], [key length], cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
const unsigned char * buffer = (const unsigned char *)[HMAC bytes];
NSMutableString *HMACString = [NSMutableString stringWithCapacity:HMAC.length* 2];
for (int i = 0; i < HMAC.length; i++) {
[HMACString appendFormat:@“%02x”, buffer[i]];
}
return HMACString;
}
Android HMAC (hex): 512B5CE2EA1CD71FF34C9DDB693F59288EF71B42
iOS HMAC: 96f852a08d3ee255b77364a6bbd106be0dc0e44e
Может кто-нибудь уточнить, пожалуйста, как я могу получить тот же HMAC, что и iOS (потому что он соответствует конечному результату).
0 ответов
Наконец, я достиг того же результата, что и для iOS, только с использованием библиотеки openssl C (предварительно созданной для NDK), вот код cpp:
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_speicherbox_speicherbox_utils_CryptoUtils_hmac(JNIEnv *env, jclass type, jstring key_, jstring data_) {
char *keyString = const_cast<char *>(env->GetStringUTFChars(key_, 0));
unsigned char *key = datahex(keyString);
const char *data = env->GetStringUTFChars(data_, 0);
//__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "______________________ key: %s", key);
//__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "______________________ data: %s", data);
unsigned int result_len;
unsigned char result[EVP_MAX_MD_SIZE];
HMAC(
EVP_sha1(),
key,
SHA1_DIGEST_LENGTH,
(unsigned char*)data,
strlen(data),
result,
&result_len
);
env->ReleaseStringUTFChars(key_, keyString);
env->ReleaseStringUTFChars(data_, data);
jbyteArray hmacBytes = env->NewByteArray(result_len);
env->SetByteArrayRegion(hmacBytes, 0, result_len, (jbyte*)result);
return hmacBytes;
}