【问题标题】:SHA256: different output in Swift and Java?SHA256:Swift 和 Java 中的不同输出?
【发布时间】:2017-07-30 06:51:38
【问题描述】:

我正在尝试使用 SHA256 对字符串进行编码。我知道输出应该是什么样子。 这是我从工作 Java 中得到的:

string = "1234nonce=1234"

SHA256 Hash from string in Java:

string.digest() =
[-29, -80, -60, 66, -104, -4, 28, 20, -102, -5, -12, -56, -103, 111,
-71, 36, 39, -82, 65, -28, 100, -101, -109, 76, -92, -107, -103, 27,
120, 82, -72, 85]

现在我需要在 Swift 中得到相同的结果:

 func sha256() {
        let string = "1234nonce=1234"
        let intArray = [UInt8](string.utf8)
        let data = Data(bytes: intArray)

        var hash = [UInt8](repeating: 0,  count: Int(CC_SHA256_DIGEST_LENGTH))
        data.withUnsafeBytes {
            _ = CC_SHA256($0, CC_LONG(data.count), &hash)
        }
        print(hash)
        return Data(bytes: hash)
 }

但是结果是这样的:

[218, 207, 142, 73, 87, 235, 210, 73, 201, 67, 19, 33, 57, 146, 69, 48, 51, 56, 0, 212, 172, 114, 118, 31, 102, 19, 175, 51, 153, 230, 143, 67]

第一个结果是如何在Java中产生的,你可以在最后一个答案中看到here。 (那里,nonce + data 对应于"1234nonce=1234") 我想知道是否有什么我做错了。非常感谢任何形式的帮助。

【问题讨论】:

    标签: java ios swift cocoa sha


    【解决方案1】:

    简答

    看来你用 Swift 语言实现的 SHA-256 哈希算法是正确的。

    长答案

    The Java example you are referring to 不仅包含 SHA-256 哈希算法实现,还包含 HMAC-SHA-512 算法实现来计算签名 (?)。

    总而言之,如果只需要SHA-256算法,请查看以下草稿 Java实现:

    package com.thecompany.test;
    
    import java.nio.charset.StandardCharsets;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    class Program {
        public static void main(final String[] args) throws NoSuchAlgorithmException {
            // Input.
            final String input = "1234nonce=1234";
    
            // Processing.
            final byte[] output = sha256(input);
    
            // Output.
            System.out.printf("Signed output: %s.%n", Arrays.toString(output));
    
            final List<Integer> unsignedOutput = unsignedIntStream(output)
                .boxed()
                .collect(Collectors.toList());
            System.out.printf("Unsigned output: %s.%n", unsignedOutput);
        }
    
        private static IntStream unsignedIntStream(final byte[] array) {
            return IntStream
                .range(0, array.length)
                .map(index -> Byte.toUnsignedInt(array[index]));
        }
    
        private static byte[] sha256(final String text) throws NoSuchAlgorithmException {
            final MessageDigest digest = MessageDigest.getInstance("SHA-256");
            return digest.digest(text.getBytes(StandardCharsets.UTF_8));
        }
    }
    

    程序产生以下输出:

    Signed output: [-38, -49, -114, 73, 87, -21, -46, 73, -55, 67, 19, 33, 57, -110, 69, 48, 51, 56, 0, -44, -84, 114, 118, 31, 102, 19, -81, 51, -103, -26, -113, 67].
    Unsigned output: [218, 207, 142, 73, 87, 235, 210, 73, 201, 67, 19, 33, 57, 146, 69, 48, 51, 56, 0, 212, 172, 114, 118, 31, 102, 19, 175, 51, 153, 230, 143, 67].
    

    希望这会有所帮助。

    【讨论】:

    • 谢谢,这让我平静了一点。我不明白的是:参考答案的作者写了所有散列输出结果,这些结果最终导致最终签名。我尝试了最终的签名,它奏效了。所以一方面,他的代码肯定是正确的。但也许他没有正确命名它。这是他写的关于第一个哈希的内容:
    • nonce + data = "1234nonce=1234" the SHA256 Hash from nonce + data in Java is: md.digest() = [-29, -80, -60, 66, -104, -4, 28, 20, -102, -5, -12, -56, -103, 111, -71, 36, 39, -82, 65, -28, 100, -101, -109, 76, -92, -107, -103, 27, 120, 82, -72, 85]
    • 也许他把它弄混了,我不知道,但我正在努力继续,希望我最终会得到相同的签名。是的,它必须成为一个签名,我正在尝试快速构建所有这些。
    • «是的,它必须成为一个签名,我正在尝试快速构建这一切。»美好的。那么就需要对Swift实现进行适当的更新:引入合适的HMAC-SHA-512算法实现。
    • 是的,当然。 Here 你可以看到指南:(URI path + SHA256(nonce + POST data)) 所以对于nonce + POST data,应该只使用 SHA256。之后是 HMAC-SHA-512 算法实现。仍然不明白为什么他会得出不同的结果。但我继续前进,希望我最终会得到相同的签名。
    猜你喜欢
    • 2011-06-08
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多