Я работал над этим в течение нескольких дней.
У нашего бэкэнда есть проверка подписи, которая выполняется с помощью PHP:
private $HMAC_ALGO = 'md5';
public function decodeAndValidateMessage($data,$signature,$secretkey) {
if (!is_string($data)) {
throw new InvalidRequestException($data);
}
$decodedData = base64_decode($data);
// if not json returned the throw exception...
$jsonDecoded = json_decode($decodedData,true);
if (!$jsonDecoded) {
throw new InvalidRequestException($decodedData);
}
// validate
$signatureRef = base64_encode(hash_hmac($this->HMAC_ALGO,$decodedData,$secretkey,true));
if ($signature === $signatureRef) {
return $jsonDecoded;
} else {
throw new InvalidSignatureException();
}
}
Я заставил его работать на iOS:
func hmac(_ algorithm: HMACAlgorithm, key: String) -> String {
let cKey = key.cString(using: String.Encoding.utf8)
let cData = self.cString(using: String.Encoding.utf8)
var result = [CUnsignedChar](repeating: 0, count: Int(algorithm.digestLength()))
CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, Int(strlen(cKey!)), cData!, Int(strlen(cData!)), &result)
let hmacData:Data = Data(bytes: UnsafePointer<UInt8>(result), count: (Int(algorithm.digestLength())))
let hmacBase64 = hmacData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
print(String(hmacBase64))
return String(hmacBase64)
}
Любая идея / помощь по этому вопросу на Kotlin / Android?Я застрял на InvalidSignatureException
ошибка.
fun generateSignature(data : HashMap<String, Any>) : String {
val hmac = Mac.getInstance("HmacMD5")
hmac.init(SecretKeySpec(Constant.PRIVATEKEY.toByteArray(Charsets.UTF_8), hmac.algorithm))
return Base64.encodeToString(data.toString().toByteArray(),Base64.URL_SAFE + Base64.NO_PADDING + Base64.NO_CLOSE + Base64.NO_WRAP)
}
Спасибо: D Я действительно признателен за любую помощь: D
Обновление:
Просто чтобы упростить мой вопрос?
Можно ли перевести строку кода iOS в Kotlin?
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)
}
}
вот как я вызываю функцию
var params: Dictionary
params.generateSignature ()