gpt4 book ai didi

java - 从 Objective-C 到 Swift Base64 和 HMACSHA1

转载 作者:行者123 更新时间:2023-11-30 12:22:44 24 4
gpt4 key购买 nike

我遇到了一个问题,并尝试解决了几天,并且确实需要您的帮助。

我需要连接到API并获取带有签名参数的post请求示例

URL = yourapi.com//mobile/register?client_id=3tme3bnmepmibhvv1toq4xfed&device_id=866faaa06aa1b139D&phone= 79653502956&signature=1WVoLPXcqJVKaxSK50ArFHtKtnM=

原始数据

data ="3tme3bnmepmibhvv1toq4xfed866faaa06aa1b13979653502956"
key = "0gkp7n6tnwdn816kyzfp26s3e"

主要问题在于签名。需要这样生成

Java 示例

signature = Base64.encode(HMAC_SHA1.digest(data, Base64.decode(client_secret)))

我有旧的 Objective-C 代码,可以与 base64 和 hamcsha1(CommonCrypto) 一起使用

#import "Base64.h"

@interface Base64()

@end

@implementation Base64

static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const short _base64DecodingTable[256] = {
-2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
-2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
};

+ (NSString *) encodeString: (NSString *) strData {
return [self encodeData: [strData dataUsingEncoding: NSUTF8StringEncoding] ];
}

+ (NSString *) encodeData: (NSData *) objData {
const unsigned char * objRawData = [objData bytes];
char * objPointer;
char * strResult;

// Get the Raw Data length and ensure we actually have data
unsigned long intLength = [objData length];
if (intLength == 0) return nil;

// Setup the String-based Result placeholder and pointer within that placeholder
strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char));
objPointer = strResult;

// Iterate through everything
while (intLength > 2) { // keep going until we have less than 24 bits
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
*objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];

// we just handled 3 octets (24 bits) of data
objRawData += 3;
intLength -= 3;
}

// now deal with the tail end of things
if (intLength != 0) {
*objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
if (intLength > 1) {
*objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
*objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
*objPointer++ = '=';
} else {
*objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
*objPointer++ = '=';
*objPointer++ = '=';
}
}

// Terminate the string-based result
*objPointer = '\0';

// Return the results as an NSString object
NSString *result = @(strResult);

free(strResult);

return result;
}

+ (NSData *) decodeString: (NSString *) strBase64 {
const char * objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding];
unsigned long intLength = strlen(objPointer);
int intCurrent;
int i = 0, j = 0, k;

unsigned char * objResult;
objResult = calloc(intLength, sizeof(unsigned char));

// Run through the whole string, converting as we go
while ( ((intCurrent = *objPointer++) != '\0') && (intLength-- > 0) ) {
if (intCurrent == '=') {
if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) {
// the padding character is invalid at this point -- so this entire string is invalid
free(objResult);
return nil;
}
continue;
}

intCurrent = _base64DecodingTable[intCurrent];
if (intCurrent == -1) {
// we're at a whitespace -- simply skip over
continue;
} else if (intCurrent == -2) {
// we're at an invalid character
free(objResult);
return nil;
}

switch (i % 4) {
case 0:
objResult[j] = intCurrent << 2;
break;

case 1:
objResult[j++] |= intCurrent >> 4;
objResult[j] = (intCurrent & 0x0f) << 4;
break;

case 2:
objResult[j++] |= intCurrent >>2;
objResult[j] = (intCurrent & 0x03) << 6;
break;

case 3:
objResult[j++] |= intCurrent;
break;
}
i++;
}

// mop things up if we ended on a boundary
k = j;
if (intCurrent == '=') {
switch (i % 4) {
case 1:
// Invalid state
free(objResult);
return nil;

case 2:
k++;
// flow through
case 3:
objResult[k] = 0;
}
}

// Cleanup and setup the return NSData
NSData * objData = [[NSData alloc] initWithBytes:objResult length:j] ;
free(objResult);
return objData;

}

@end

休息客户端中的 Objective-c

+ (NSString*)signParametersWithString:(NSString*)parameters
withSecret:(NSString*)clientSecret
{
// Base64 Decode.
NSData* keyData = [Base64 decodeString:clientSecret];
NSString *strData = [[NSString alloc]initWithData:keyData encoding:NSUTF8StringEncoding];

// DO NOT USE !!! [[NSData alloc] initWithBase64EncodedString:clientSecret options:0];

const char* cData = [parameters cStringUsingEncoding:NSASCIIStringEncoding];

unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];

// Sign with HMAC SHA1.
CCHmac(kCCHmacAlgSHA1, [keyData bytes], [keyData length], cData, strlen(cData), cHMAC);

NSData* HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

// Base64 Encode.
NSLog(@"%@", HMAC);
return [HMAC base64EncodedStringWithOptions:0];

}

我试图通过 StackOverflow 社区快速实现它,但它不起作用。

Swift 代码

        let data = Data("3tme3bnmepmibhvv1toq4xfed866faaa06aa1b13979653502956".utf8)
let key = Data("0gkp7n6tnwdn816kyzfp26s3e".utf8).base64EncodedString()
let hmac = data.hmacsha1(key: key)

extension Data {

func hmacsha1(key: String) -> String? {
guard let keyData = Data(base64Encoded: key) else {
return nil
}
var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
self.withUnsafeBytes({ dataBytes in
keyData.withUnsafeBytes({ keyDataBytes in
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), keyDataBytes, keyData.count, dataBytes, self.count, &digest)
})
})
return Data(bytes: digest).base64EncodedString()
}
}

它正在生成。

signature = "pd6oB8P8Yq92gn7eYH0qAnSLFbI="

但是我需要这个

signature = "1WVoLPXcqJVKaxSK50ArFHtKtnM="

我需要帮助来修复 swift func 或如何使 obj-c 代码在 Swift 项目中工作。我认为这是解码 Base64 的错误,但我现在不知道如何弄清楚。

最佳答案

问题已解决

let keyData: NSData = Base64.decode(secret_key) as NSData
let cData = param_signature


let hmacResult: String = cData.hmac(algorithm: HMACAlgorithm.SHA1, key: keyData)


enum HMACAlgorithm {
case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

func toCCHmacAlgorithm() -> CCHmacAlgorithm {
var result: Int = 0
switch self {
case .MD5:
result = kCCHmacAlgMD5
case .SHA1:
result = kCCHmacAlgSHA1
case .SHA224:
result = kCCHmacAlgSHA224
case .SHA256:
result = kCCHmacAlgSHA256
case .SHA384:
result = kCCHmacAlgSHA384
case .SHA512:
result = kCCHmacAlgSHA512
}
return CCHmacAlgorithm(result)
}

func digestLength() -> Int {
var result: CInt = 0
switch self {
case .MD5:
result = CC_MD5_DIGEST_LENGTH
case .SHA1:
result = CC_SHA1_DIGEST_LENGTH
case .SHA224:
result = CC_SHA224_DIGEST_LENGTH
case .SHA256:
result = CC_SHA256_DIGEST_LENGTH
case .SHA384:
result = CC_SHA384_DIGEST_LENGTH
case .SHA512:
result = CC_SHA512_DIGEST_LENGTH
}
return Int(result)
}
}

extension String {
func hmac(algorithm: HMACAlgorithm, key: NSData) -> String {
let cKey = key
let cData = self.cString(using: String.Encoding.ascii)
var cHMAC = [CC_SHA1_DIGEST_LENGTH]
CCHmac(algorithm.toCCHmacAlgorithm(), cKey.bytes, cKey.length, cData, Int(strlen(cData!)), &cHMAC)
let hmacData:NSData = NSData(bytes: cHMAC, length: (Int(algorithm.digestLength())))
let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
return String(hmacBase64)
}
}

关于java - 从 Objective-C 到 Swift Base64 和 HMACSHA1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44591743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com