简体   繁体   English

如何使用SWIFT 4创建HMAC MD5十六进制签名?

[英]How to create a HMAC MD5 Hex signature using SWIFT 4?

I'm trying to create a HMAC MD5 Hex signature using SWIFT 4. 我正在尝试使用SWIFT 4创建HMAC MD5十六进制签名。

We'll use a sample string -> "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non metus erat. Nam nec dolor ut neque suscipit viverra in sit amet odio. Cras eleifend sed risus eget luctus" 我们将使用示例字符串->“ Lorem ipsum dolor sit amet,consectetur adipiscing elit。Donec non metus erat。Nam nec dolor ut neque suscipit viverra in sit amet odio。Cras eleifend sed risus eget luctus”

a sample key -> "6fa9b1de89d0707f6dc952349166bbe7" 示例密钥-> "6fa9b1de89d0707f6dc952349166bbe7"

The result in my code is "dd2cef2b06ddb08e16c32a4ddc583d11" 我的代码中的结果是"dd2cef2b06ddb08e16c32a4ddc583d11"

The result on most websites is "dd2cef2b06ddb08e16c32a4ddc583d11" 大多数网站上的结果是"dd2cef2b06ddb08e16c32a4ddc583d11"

The result on Cryptii.com is "7eda9d3c1356402e6fce39af3bc8d195" Cryptii.com上的结果是"7eda9d3c1356402e6fce39af3bc8d195"

The payment handler uses the exact signature from Cryptii.com as reference and I cannot generate it in iOS, using swift 4. I used the CryptoSwift library and others( https://gist.github.com/MihaelIsaev/f913d84b918d2b2c067d , Implementing HMAC and SHA1 encryption in swift ). 付款处理程序使用来自Cryptii.com的确切签名作为参考,我无法使用swift 4在iOS中生成它。我使用了CryptoSwift库和其他库( https://gist.github.com/MihaelIsaev/f913d84b918d2b2c067d实现HMAC和sw1的SHA1加密 )。

I use this code (from CryptoSwift): 我使用以下代码(来自CryptoSwift):

let keyArr: Array<UInt8> = Array(key.utf8) 
let stringArr: Array<UInt8> = Array(string.utf8) 
do { 
let a = HMAC.init(key: keyArr, variant: .md5) 
let encrypted3 = try a.authenticate(stringArr) 
print("Encrypted string: (encrypted3.toHexString())") 
} catch { } 

Any ideas? 有任何想法吗?

Thanks! 谢谢!

The android implementation looks like this and it works: android实现看起来像这样,它的工作原理是:

private String getFpHash(String source, String secretKey) {
    try {
        Mac mac = Mac.getInstance("HmacMD5");
        byte[] hexKeyBytes = HexEncoder.toBytesFromHex(secretKey);
        mac.init(new SecretKeySpec(hexKeyBytes, "HmacMD5"));
        String hexEncoded = HexEncoder.toHexFromBytes(mac.doFinal(source.getBytes()));
        return hexEncoded;
    }
    catch (Exception e) {
        return null;
    }
}

public class HexEncoder
{
   public static final String[] HEX_TABLE = new String[]{
            "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
            "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
            "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
            "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
            "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
            "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
            "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
            "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
            "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
            "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
            "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
            "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
            "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
            "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
            "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
            "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
    };

    public static byte[] toBytesFromHex(String hex) {
        byte rc[] = new byte[hex.length() / 2];
        for (int i = 0; i < rc.length; i++) {
            String h = hex.substring(i * 2, i * 2 + 2);
            int x = Integer.parseInt(h, 16);
            rc[i] = (byte) x;
        }
        return rc;
    }

    public static String toHexFromBytes(byte[] bytes) {
        StringBuffer rc = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            rc.append(HEX_TABLE[0xFF & bytes[i]]);
        }
        return rc.toString();
    }
}

On the shoulders of giants etc., using this extension to split your key string up into pairs of characters: 在巨人等的肩膀上,使用此扩展将您的密钥字符串拆分为成对的字符:

// From https://stackoverflow.com/a/34454633/325366
extension Collection {
    var pairs: [SubSequence] {
        var startIndex = self.startIndex
        let count = self.count
        let n = count/2 + count % 2
        return (0..<n).map { _ in
            let endIndex = index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex
            defer { startIndex = endIndex }
            return self[startIndex..<endIndex]
        }
    }
}

... we can turn your key String into a [UInt8] : ...我们可以将您的键String转换为[UInt8]

let keyBytes = key.pairs.map { byteStr -> UInt8 in
    var value: UInt32 = 0
    Scanner(string: String(byteStr)).scanHexInt32(&value)
    return UInt8(clamping: value)
}

... and anticipating a desire to print the final hex value out we can write an extension on Array : ...并且期望打印出最终的十六进制值的愿望,我们可以在Array上编写扩展名:

extension Array where Element == UInt8 {
    var asHexString: String {
        return self.map { String(format: "%0x", $0) }
                   .joined()
    }
}

... which results in your original code: ...这将导致您的原始代码:

let stringArr: Array<UInt8> = Array(string.utf8)
do {
    let authenticator = HMAC(key: keyBytes, variant: .md5)
    let hmac = try authenticator.authenticate(stringArr)

    print("Message HMAC: \(hmac.asHexString)")
} catch { }

... printing out the value you are looking for: ...打印出您想要的值:

Encrypted string: 7eda9d3c1356402e6fce39af3bc8d195

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM