美文网首页iOS那些坑
谈谈iOS加密:AES+RSA

谈谈iOS加密:AES+RSA

作者: zgsddzwj | 来源:发表于2017-08-18 21:08 被阅读889次

最近在项目中需要对用户信息及数据传输进行加密,网上搜索了下相关信息,最后决定采用AES+RSA的方式。
AES:对称加密,加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高。
RSA:非对称加密,使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。
所以我们结合两者的特性,采用AES对传输的数据进行加密,然后采用RSA对AES的秘钥进行加密。AES的秘钥是客户端生成的(iOS我采用的是UUID),然后把AES的秘钥用不可逆的RSA加密,最后发送给服务器的是RSA加密过的AES的秘钥和AES加密的数据(是不是有点晕~)。服务器端保留RSA的私钥,可以对AES的秘钥进行解密,然后用AES的秘钥解密数据。这样就拿到客户端的数据了。服务器进行数据处理过后,用传过来的AES的秘钥加密数据再传给客户端。
说的比较笼统,具体的逻辑可以参考以下链接:http://www.jianshu.com/p/ec7bb7325ff2

关于AES的集成,网上也是众说纷纭,以下是我的实现方式:

//MARK:AES加密
func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = self.data(using: String.Encoding.utf8),
            let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {


            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCEncrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)



            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      (data as NSData).bytes, data.count,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString


            }
            else {
                return nil
            }
        }
        return nil
    }

    //MARK:AES解密
    func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.data(using: String.Encoding.utf8),
            let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
            let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

            let keyLength              = size_t(kCCKeySizeAES128)
            let operation: CCOperation = UInt32(kCCDecrypt)
            let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
            let options:   CCOptions   = UInt32(options)

            var numBytesEncrypted :size_t = 0

            let cryptStatus = CCCrypt(operation,
                                      algoritm,
                                      options,
                                      (keyData as NSData).bytes, keyLength,
                                      iv,
                                      data.bytes, data.length,
                                      cryptData.mutableBytes, cryptData.length,
                                      &numBytesEncrypted)

            if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                cryptData.length = Int(numBytesEncrypted)
                let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
                return unencryptedMessage
            }
            else {
                return nil
            }
        }
        return nil
    }

关于aes key、iv的意义:参见:http://www.jianshu.com/p/df828a57cb8f
集成后,可以到https://blog.zhengxianjun.com/online-tool/crypto/aes/进行验证。

RSA的集成就更恶心了。关于RSA的公钥、私钥的生成,有iOS自己生成和服务器端生成两种方式(具体的解释请自行Google~),我们采用的是服务器端生成。拿到服务器给的公钥后,怎么用呢??

有人说,用SecrecySwift(参见:http://swiftcn.io/topics/84),集成BBRSACryptor过程中发现openssl怎么都报错,感谢http://www.jianshu.com/p/1e5f214ad789这篇博客详细的解释,但是最后集成到项目中还是报错。于是又搜索了番。发现https://github.com/ideawu/Objective-C-RSA这个共享库(人民群众的力量强大啊~~),最后简单的集成,测试(测试地址:https://blog.zhengxianjun.com/online-tool/rsa/),通过,阿弥陀佛!!

至此,可以开森的进行加密了。

不是所有的数据传输都需要这么严格的加密的。一般只是对用户名的密码、支付等相关信息才需要这么复杂的加密的。对于普通请求,我们采用的是MD5。

MD5也是不可逆的加密。主要用于服务器上存储用户的密码。 用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并不“知道”用户的密码是什么。

我们知道,如果直接对密码进行散列,那么黑客可以对通过获得这个密码散列值,然后通过查散列值字典(例如MD5密码破解网站),得到某用户的密码。

加Salt可以一定程度上解决这一问题。所谓加Salt方法,就是加点“佐料”。其基本想法是这样的:当用户首次提供密码时(通常是注册时),由系统自动往这个密码里撒一些“佐料”,然后再散列。而当用户登录时,系统为用户提供的代码撒上同样的“佐料”,然后散列,再比较散列值,已确定密码是否正确。

这里的“佐料”被称作“Salt值”,这个值是由系统随机生成的,并且只有系统知道。这样,即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。即便黑客可以通过自己的密码和自己生成的散列值来找具有特定密码的用户,但这个几率太小了(密码和salt值都得和黑客使用的一样才行)。

补充一点:客户端在向服务端接口进行请求,如果请求信息进行了加密处理,被第三方截取到请求包,虽然第三方无法解密获取其中的数据,但是可以使用该请求包进行重复的请求操作。如果服务端不进行防重放攻击,就会参数服务器压力增大,数据紊乱的后果。而使用添加时间戳的方式可以解决这一问题。在请求中,除了时间戳,再添加一个nonce参数,这样时间戳允许十五分钟偏差,那么服务器只要记录十五分钟以内的nonce参数就行了,这样可以避免重放攻击。

赋下MD5的加密方法。

//MARK:MD5 加密方式 不可逆
    var MD5: String! {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)

        CC_MD5(str!, strLen, result)

        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }

        result.deallocate(capacity: digestLen)

        return hash as String
    }

本人QQ:297959735 邮箱:zgsddzwj@163.com,欢迎提意见。

相关文章

  • 谈谈iOS加密:AES+RSA

    最近在项目中需要对用户信息及数据传输进行加密,网上搜索了下相关信息,最后决定采用AES+RSA的方式。AES:对称...

  • iOS使用AES+RSA加密

    由于项目中,登录请求过程中涉及到用户数据的传输,为了用户数据的安全性考虑,决定在请求与相应中使用加密传输的方式。查...

  • AES+RSA加密联合使用

    AES+RSA加密联合使用 使用原因: 因为加密解密效率的问题 使用方式前端:前端对需要加密的数据进性AES加密,...

  • 关于Android和iOS兼容的那一点点小事

    1.首先讲讲在加密时候遇到的问题,缘起:公司的前后端交互涉及到加密,加密策略是aes+rsa,我们后台竟然用了一套...

  • Okhttp/Retrofit网络请求加解密实现方案

    一、加密方案 比较安全的方案应该是AES+RSA的加密方式。具体如下图(此图源于网络)所示。 为什么要这样做呢?1...

  • AES+RSA加密流程

    在网络请求中,使用http协议在传输过程中数据很容易被人截取,那对数据的加密就显得很重要。在不使用https的情况...

  • 谈谈iOS几种加密

    背景 在开发应用的时候,数据的安全性至关重要,而仅仅用POST请求提交用户的隐私数据,还是不能完全解决安全问题。 ...

  • AES+RSA加密——Android版

    Android端 AES+RSA结合实践 基本要求 保证传输数据的安全性 保证数据的完整性 能够验证客户端的身份 ...

  • iOS开发中数据传输使用AES+RSA加密

    前段时间工作的内容中涉及到传输数据的加密,加密方式是AES+RSA,具体过程中也参考了一些网上的文章,简单写一个记...

  • iOS 加密算法 CommonCrypto框架①【待补充】

    iOS 加密算法 iOS CommonCrypto框架① iOS 加密算法 iOS CommonCrypto框架②...

网友评论

  • 山山逗:你好,请问下前台和后台用AES约定好秘钥不就可以了吗?为什么要用RSA传AES的秘钥
    zgsddzwj:@山山逗 约定好秘钥,前台的数据有可能被别人抓包获取到

本文标题:谈谈iOS加密:AES+RSA

本文链接:https://www.haomeiwen.com/subject/pcqzrxtx.html