iOS MD5,SHA,Base64介绍

MD5

什么是MD5

它是一种信息摘要算法,并不是加密算法(以下是习惯性的说成MD5加密),它可以从一个字符串或一个文件中按照一定的规则生成一个特殊的字符串(这个特殊的字符串就被称之为摘要,我理解就是从文件中摘一些信息片段加工而来),并且一个文件所对应的MD5摘要是固定的,当文件内容变化后,其MD5值也会不一样。MD5值就是指这串32位的由“0-9,a-f”所组成的字符串

MD5的特点:

  • 不可逆运算
  • 对不同的数据加密的结果是定长的32位字符(不管文件多大都一样)
  • 对相同的数据加密,得到的结果是一样的(也就是复制)。
  • 抗修改性 : 信息“指纹”,对原数据进行任何改动,哪怕只修改一个字节,所得到的 MD5 值都有很大区别.
  • 确定性 : 已知原数据和其 MD5 值,想找到一个具有相同 MD5 值的数据(即伪造数据)是非常困难的.
  • 碰撞性: 想找到两个不同数据,使他们具有相同的 MD5 值,是非常困难的

MD5 应用:

  • 对密码进行加密,移动端会将用户密码通过MD5加密转换后发送给服务器,服务器会在数据库中保存加密后的md5值。这样做的好处是不会直接发送明文密码、服务器管理人员也无法确切的知道密码。但是一旦拿到密码的md5值后仍然存在被暴力破解的可能性。破解网站

  • 文件的完整性校验,在传递文件的过程中附带传递文件的md5值,接收端通过比较文件的md5值判断文件的完整性。

增强MD5的安全性

1.对明文多次MD5加密,对明文加密之后的MD5串再次进行MD5加密

2.MD5加盐(salt),基本过程是这样的:当需要对明文进行MD5加密的时候,程序会添加一个salt值跟明文一起进行MD5加密,这样可以极大增强MD5被破解的难度。salt值可以是随机字符串或者username+password这种形式,当使用随机字符串作为salt加密是通常需要将salt一起上传服务器进行保存。

代码实现

import Foundation
import CommonCrypto
extension String{
    var md5:String {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<UInt8>.allocate(capacity: 16)
        CC_MD5(str, strLen, result)
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        free(result)
        return String(format: hash as String)
    }
}

print("这是MD5".md5)

SHA 安全散列算法

什么是SHA

安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族.
和MD5类似,安全散列算法可以根据字符串生成一定长度的摘要信息,该摘要信息不可逆转,且不同的字符串的摘要信息相同的概率极低。

SHA家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,由美国国家安全局(NSA)所设计,并由美国国家标准与技术研究院(NIST)发布;是美国的政府标准。后四者有时并称为SHA-2。SHA-1在许多安全协定中广为使用,包括TLSSSLPGPSSH、S/MIME和IPsec,曾被视为是MD5(更早之前被广为使用的杂凑函数)的后继者。

SHA的使用

import Foundation
import CommonCrypto
extension String{
    enum SHAType{
        case sha1,sha224,sha256,sha384,sha512
    }
    
    func sha(_ type:SHAType) -> String{
        var digestLen:Int = 0
        switch type {
        case .sha1:
            digestLen = Int(CC_SHA1_DIGEST_LENGTH)
        case .sha224:
            digestLen = Int(CC_SHA224_DIGEST_LENGTH)
        case .sha256:
            digestLen = Int(CC_SHA256_DIGEST_LENGTH)
        case .sha384:
            digestLen = Int(CC_SHA384_DIGEST_LENGTH)
        case .sha512:
            digestLen = Int(CC_SHA512_DIGEST_LENGTH)
        }
        
        let unsafePointer = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let result = UnsafeMutablePointer<UInt8>.allocate(capacity: digestLen * 2)
        
        switch type {
        case .sha1:
            CC_SHA1(unsafePointer, strLen, result)
        case .sha224:
            CC_SHA224(unsafePointer, strLen, result)
        case .sha256:
            CC_SHA256(unsafePointer, strLen, result)
        case .sha384:
            CC_SHA384(unsafePointer, strLen, result)
        case .sha512:
            CC_SHA512(unsafePointer, strLen, result)
        }
        
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        free(result)
        return String(format: hash as String)
    }
}

print("这是SHA".sha(.sha1))
print("这是SHA".sha(.sha224))
print("这是SHA".sha(.sha256))
print("这是SHA".sha(.sha384))
print("这是SHA".sha(.sha512))
/*输出:
 859aa498c20aa785a1e516052d553bfaddc6271c
 3d4374ec9ee000f77821730f0ee71394b71b18e65c747032018f841c
 4ba0bcea71b037b45b759735a47cf173fb3e40ee4eabdf3ddeb3fe0c096d71f9
 df1b5170eeb6c665a09a20ca763768a5026bfd294ebb2c80384d43e347ea5ffaf1746fa292ab2d97bd6ff87076e3496c
 a40560b861adf2daeb8d5c81e8eb099067e33b60d4f1cfa8555c7ab991ea022a45f29e70aaa26b6ee59adab8cd52677b653524aea12758f2d798463981818d65
 */

Base64编码

什么是Base64

**Base64不是加密方式,而是编码方式,是网络上最常见的用于传输8Bit字节码的编码方式之一。**Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

####Base64的原理

可以参考Base64的原理

Base64的使用

extension String{
      ///base64 解码
      var base64Decoded: String? {
          guard let decodedData = Data(base64Encoded: self) else { return nil }
          return String(data: decodedData, encoding: .utf8)
      }
      
      ///base64 编码
      var base64Encoded: String? {
          let plainData = data(using: .utf8)
          return plainData?.base64EncodedString()
      }
}

let a = "这是base64编码".base64Encoded
print(a ?? "")                  //6L+Z5pivYmFzZTY057yW56CB
print(a?.base64Decoded ?? "")   //这是base64编码
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章