Hash (散列函数)
1.Hash定义
Hash:把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
2.哈希的特点
1.同样的输入会有同样的哈希值。
2.同一个哈希值可以从不同的输入得到。
3.任意长度的输入得到的输出长度固定,也就是说这种算法是不可以逆的。
3.哈希的用途
- 数字签名
- 文件比对,同一个文件的hash值是一样的,而且Hash值是很难重复的。
- git 提交的版本对比号码
- 原文加密,比如用户的密码。在客户端和服务器直接使用加密后的密码,这样黑客很难得到用户的真实输入的密码。
4.常用的函数
// data 需要加密的数据 len 加密数据的长度 md 加密后的结果
//MD5
CC_MD5(const void *data, CC_LONG len, unsigned char *md)
// SHA1
CC_SHA1(const void *data, CC_LONG len, unsigned char *md)
// SHA256
CC_SHA256(const void *data, CC_LONG len, unsigned char *md)
5.高级版的哈希算法 - HMAC
HMAC是密钥相关的哈希运算消息认证码(HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。
// SHA512
CC_SHA512(const void *data, CC_LONG len, unsigned char *md)
// CCHmac
/* algorithm 有:
kCCHmacAlgSHA1,
kCCHmacAlgMD5,
kCCHmacAlgSHA256,
kCCHmacAlgSHA384,
kCCHmacAlgSHA512,
kCCHmacAlgSHA224
*/
// key 加固数据
void CCHmac(
CCHmacAlgorithm algorithm, /* kCCHmacAlgSHA1, kCCHmacAlgMD5 */
const void *key,
size_t keyLength, /* length of key in bytes */
const void *data,
size_t dataLength, /* length of data in bytes */
}
6.终端生成Hash 值命令, 我们义字符串 “hello world” 为例
md5 -s "hello world" //MD5
echo -n "hello world"" | openssl sha -sha1 //SHA1
echo -n "hello world"" | openssl sha -sha256 //SHA256
echo -n "hello world"" | openssl sha -sha512 //SHA512
echo -n "hello world"" | openssl dgst -md5 -hmac "key" //HMAC + MD5
echo -n "hello world"" | openssl sha -sha1 -hmac "key" /HMAC + SHA1
echo -n "hello world"" | openssl sha -sha256 -hmac "key" /HMAC + SHA256
echo -n "hello world"" | openssl sha -sha512 -hmac "key" /HMAC + SHA512
Hash 破解与防范
破解原理
- 通过穷举字符组合的方式,创建了明文密文对应查询数据库。 这种破解的一般是密码,这种简单的字符串
- 获得签名的规则和加盐值,进行重签名,然后就可以更改参数的值
防范
- 对于密码的转化,可以使用更难穷举的HMAC
- 对于重签名,加盐的参数不放在客户端【客户端可逆向获取】
- 对于网络传输加盐值可以截取的问题,可以将这个设置一个时效性。
- 参数不要采用明文,可以使用一定的加密方式
对称加密
常见的对称加密方式
DES 3DES AES "高级"加密标准
ECB 电子代码本,每个块都是独立加密的
CBC 密码块链:使用一个密钥和一个初始化向量 (IV)对数据执行加密转换,可以有效地保证密文的完整性。
重要的函数
CCCryptorStatus CCCrypt(
CCOperation op, /* kCCEncrypt, etc. */
CCAlgorithm alg, /* kCCAlgorithmAES128, etc. */
CCOptions options, /* kCCOptionPKCS7Padding, etc. */
const void *key,
size_t keyLength,
const void *iv, /* optional initialization vector */
const void *dataIn, /* optional per op and alg */
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
enum {
kCCModeECB = 1,
kCCModeCBC = 2,
kCCModeCFB = 3,
kCCModeCTR = 4,
kCCModeF8 = 5, // Unimplemented for now (not included)
kCCModeLRW = 6, // Unimplemented for now (not included)
kCCModeOFB = 7,
kCCModeXTS = 8,
kCCModeRC4 = 9,
kCCModeCFB8 = 10,
};
参数说明
1.CCOperation: kCCEncrypt:加密, kCCDecrypt:解密
2.alg 加密解密方式
2.1 kCCAlgorithmAES128 = 0
2.2 kCCAlgorithmAES = 0
2.3 kCCAlgorithmDES,
2.4 kCCAlgorithm3DES,
2.5 kCCAlgorithmCAST,
2.6 kCCAlgorithmRC4,
2.7 kCCAlgorithmRC2,
2.8 kCCAlgorithmBlowfish
3.options 加密选项 kCCOptionPKCS7Padding | kCCOptionECBMode 如果用了iv 就有 kCCOptionECBMode
4.key 加密解密的密钥
5.keyLength 加密的长度, 根据alg 类型取对应的长度
6.iv 初始化向量
7.dataIn 加密数据
8.dataInLength 加密数据的长度
9.dataOut 加密解密后的数据
10.dataOutAvailable dataOut的长度
11.dataOutMoved 数据最后的长度
非对称加密
重要函数
SecKeyDecrypt(
SecKeyRef key, /* Private key */
SecPadding padding, /* kSecPaddingNone,kSecPaddingPKCS1, kSecPaddingOAEP */
const uint8_t *cipherText,
size_t cipherTextLen,/* length of cipherText */
uint8_t *plainText,
size_t *plainTextLen)
SecKeyDecrypt 使用公钥加密
SecKeyRef 公钥
SecPadding
cipherText 加密的数据
cipherTextLen 加密数据的长度
plainText 结果数据
plainTextLen 数据结果的长度
SecKeyDecrypt 使用私钥解密
SecKeyDecrypt(
SecKeyRef key, /* Private key */
SecPadding padding,/* kSecPaddingNone, kSecPaddingPKCS1,kSecPaddingOAEP */
const uint8_t *cipherText,
size_t cipherTextLen,/* length of cipherText */
uint8_t *plainText,
size_t *plainTextLen)