【发布时间】:2014-07-21 21:27:27
【问题描述】:
我正在我的 Android 应用程序中使用 HMAC SHA256 创建 base64 哈希。并将其发送到服务器以与服务器端哈希匹配。
关注this教程。
工作 Android 代码:
public String getHash(String data,String key)
{
try
{
String secret = key;
String message = data;
Mac sha256_HMAC = Mac.getInstance("HmacMD5");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacMD5");
sha256_HMAC.init(secret_key);
String hash = Base64.encodeBase64String(sha256_HMAC.doFinal(message.getBytes()));
System.out.println(hash);
return hash;
}
catch (Exception e){
System.out.println("Error");
}
}
服务器代码在 C# 脚本中,如下所示
using System.Security.Cryptography;
namespace Test
{
public class MyHmac
{
private string CreateToken(string message, string secret)
{
secret = secret ?? "";
var encoding = new System.Text.ASCIIEncoding();
byte[] keyByte = encoding.GetBytes(secret);
byte[] messageBytes = encoding.GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
}
}
但在android端生成的hash key与服务器端不匹配,下面是目标c代码,生成与C#代码相同
目标c代码:
#import "AppDelegate.h"
#import <CommonCrypto/CommonHMAC.h>
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString* key = @"secret";
NSString* data = @"Message";
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSLog(@"%@", hash);
NSString* s = [AppDelegate base64forData:hash];
NSLog(s);
}
+ (NSString*)base64forData:(NSData*)theData
{
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) { value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4; output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}
@end
请帮我解决这个问题, 提前致谢。
我已经通过将 HmacSHA256 更改为 HmacMD5 解决了这个问题,它给出的哈希值与 C# 代码给出的相同。
我已经用工作代码更新了我的问题。检查一下
【问题讨论】:
-
请注意,从 iOS 7 和 OSX 10.9 开始,有一种对 Base64 进行编码和解码的方法:
base64EncodedDataWithOptions:和base64EncodedStringWithOptions:。 -
您为 Android 获得了哪些价值,请参阅 psudo 答案中的 Objective-C 输出。看来这只是一个Android问题。
-
@Zaph 在 Objective-c 中的输出长度为 24,在 android 端为 42。
-
查看我的答案,它的输出长度为 42。在您的示例中提供 NSLog 语句的输出,编辑您的问题并添加这些值。
-
@Zaph 感谢您的帮助,我已经解决了问题并进行了更新。