【问题标题】:Some info about CC_SHA256 objective-c关于 CC_SHA256 目标-c 的一些信息
【发布时间】:2014-09-22 12:31:18
【问题描述】:

对于一个新项目,我需要使用 SHA256 散列一个 NSString。 我使用了以下代码:

unsigned char hashedChars[32];
NSString *inputString;
inputString = [NSString stringWithFormat:@"hello"];
NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256(inputData.bytes, inputData.length, hashedChars);

我在 stackoverflow 上找到了这段代码。 我并没有真正理解这段代码所做的所有事情,这里有一些关于代码的问题:

1.CC_SHA256做了一个hash,但是这个hash又会存入inputData?我的意思是我可以这样做:

NSString *string=CC_SHA256(..) //of course you can't put it directly in a NSString, but you get the point

2.最后hash必须是16进制字符串,但是CC_SHA256输出的类型是什么(UTF-8??)?

3.CC_SHA256的第一个参数为什么一定要在最后加上“inputData”就够了?

4.字符串的长度(第二个参数)需要什么?

5.最后一个参数对我来说没有任何意义,谁能解释一下为什么 hashedChars 必须是 32?

【问题讨论】:

    标签: objective-c sha256


    【解决方案1】:

    CC_SHA256 的参数列表是:

     extern unsigned char *CC_SHA256(const void *data, CC_LONG len, unsigned char *md);
    

    来自man 页面:https://developer.apple.com/library/ios/documentation/System/Conceptual/ManPages_iPhoneOS/man3/CC_SHA256.3cc.html

    参数说明:

    • *data 是输入字符串,你想要散列的内容。它是 C 字符串类型。一种方法是调用“inputData.bytes”,并使用inputData 一个NSData 对象。
    • len 是输入字符串的长度。正如您将意识到的那样,如果您开始使用 C 字符串,那么使用字符串的函数询问长度是很正常的。这是因为在 C 中字符串只是一个字节序列,而文本字符串通常以空字节结尾,而二进制字符串可以有任意长度。这也是为了安全(“缓冲区溢出”)。
    • *md 是输出。同样,这是作为 C 字符串返回的,对于 SHA256,它具有 32 个字节的固定长度(这就是您看不到 outputLength 参数的原因)。
    • 输出“不相关”,但可用于检查函数是否正常运行:if(CC_SHA256(...)) { all ok; }

    结果字符串存储到*md,它是一个二进制C字符串,32字节长。它有 32 个字节长,因为这是 SHA256 摘要的长度;例如,16 个字节用于 MD5,20 个字节用于 SHA1,等等。这就是算法的工作原理!
    输出只是一个二进制字符串。如果你想把它变成十六进制格式,你需要把它存储到一个 NSData 对象中,然后得到它的十六进制表示:

    NSData *resultData = [NSData dataWithBytes:hashedChars length:32];
    

    要获得十六进制表示,请查看这个 SO 答案:https://stackoverflow.com/a/25378464/192024

    【讨论】:

    • 我不确定您关于输出“不相关”的最后一点是否正确。来自 macOS Sierra 上的 man CC_SHA256:“All routines return 1 except for the one-shot routines ( CC_SHA1(), etc.), which return the pointer passed in via the md parameter.。这意味着返回值是作为 md 传入的指针,而不是任何类型的成功指示值?(您上面链接的手册页现在已经死了,感谢 Apple .)
    • 使用 CC_SHA256_DIGEST_LENGTH 比使用幻数 32 更好。
    • @alfwatt #define CC_SHA256_DIGEST_LENGTH 32 来自标头:opensource.apple.com/source/CommonCrypto/CommonCrypto-36064/… 真的应该没什么区别,我们不能改变 SHA256 的长度 :)
    • @Qualcuno 它不会改变,但最初的问题想知道为什么它是 32,使用常量有助于解释它是预期长度
    【解决方案2】:

    如果有人试图为 Android 找到类似的功能,下面的 sn-p 会产生与 CC_SHA256 相同的输出

      public static String calculateSH256(String secret){
            final MessageDigest digest;
            try {
                digest = MessageDigest.getInstance("SHA-256");
                byte[] bytes = secret.getBytes("UTF-8");
                digest.update(bytes, 0, bytes.length);
                String sig = bytesToHex(digest.digest());
                return sig;
            }
            catch (NoSuchAlgorithmException | UnsupportedEncodingException e){
             throw new RuntimeException("Cannot calculate signature");  
            }          
        }
    
    
        final protected static char[] hexArray = "0123456789abcdef".toCharArray();
    
        private static String bytesToHex(byte[] bytes) {
            char[] hexChars = new char[bytes.length * 2];
            for ( int j = 0; j < bytes.length; j++ ) {
                int v = bytes[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 2015-11-15
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多