java - JAVA和iOS的HMAC结果不同

标签 java android ios hmac sha

我正在尝试根据字符串值和键生成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(十六进位):512B5CE2EA1CD71FF34C9DDB693F59288EF71B42

iOS HMAC:96f852a08d3ee255b77364a6bbd106be0dc0e44e

有人可以澄清一下,我如何获得与iOS相同的HMAC(因为它与后端结果匹配)。

最佳答案

最终,我仅使用openssl C库(为NDK预先构建)达到了与iOS相同的结果,这是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;
}

关于java - JAVA和iOS的HMAC结果不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53324308/

相关文章:

iPhone - 如何在键盘上方创建一个滚动的 UIToolbar?

java/ant jar 文件 SecurityException

java - 寻找一种方法,使用户仅限于一个选择,否则出现非法参数异常

java - 如何正确使用可以有条件地返回值或抛出异常的Java 8 Optional?

Java GUI 登录屏幕

android - 在 android studio 中删除 Reformat Code 中未使用的导入

android - 由于 multidex/android 错误,在 Travis 中构建失败?

ios - View 上的模糊背景无法始终如一地工作

iphone - iOS 以编程方式检查调用转移是否处于事件状态

android - "W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@eb23963"是什么意思?