【ios】【android】3DES_CBC_PKCS5Padding加密、解密问题(附完整代码)

这篇具有很好参考价值的文章主要介绍了【ios】【android】3DES_CBC_PKCS5Padding加密、解密问题(附完整代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题一:加密结果不一致

一、问题描述

实现了android的蓝牙对接后开始着手ios的蓝牙对接,出现了ios加密结果与在线加密的结果一致,而android的加密结果与甲方公司的结果一致的问题。

1.android部分代码如下:
	public byte[] get3DesEncCodeCBC(byte[] byteS, byte[] key, byte[] iv) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
            SecretKey desKey = new SecretKeySpec(key, "DESede");
            IvParameterSpec desIV = new IvParameterSpec(iv);
            cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            cipher.init(cipher.ENCRYPT_MODE, desKey, desIV);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception error) {
            error.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }
2.ios部分代码如下:
	public static func CBCMain(op: Int, key: String, iv: String, content: String) -> String? {
        // op传1位加密,0为解密
        // CCOperation(kCCEncrypt)加密 1
        // CCOperation(kCCDecrypt) 解密 0
        var ccop = CCOperation();
        // Key
        let keyData: NSData = (key as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData;
        let keyBytes = UnsafeRawPointer(keyData.bytes);
        let keyLength = size_t(kCCKeySize3DES);
        // 可选的初始化向量
        let ivData: NSData = (iv as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData;
        let ivDataBytes = UnsafeRawPointer(ivData.bytes);
        // 加密或解密的内容
        if op == 1 {
            ccop = CCOperation(kCCEncrypt);
        } else {
            ccop = CCOperation(kCCDecrypt);
        }
        let data: NSData = (content as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData;
        let dataLength = size_t(data.length);
        let dataBytes = UnsafeRawPointer(data.bytes);
        // 返回数据
        let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES);
        let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes);
        let cryptLength = size_t(cryptData!.length);
        // 特定的几个参数
        let operation: CCOperation = UInt32(ccop);
        let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES);
        let options: CCOptions = UInt32(kCCOptionPKCS7Padding);
        var numBytesCrypted :size_t = 0;
        let cryptStatus = CCCrypt(operation, // 加密还是解密
                                  algoritm, // 算法类型
                                  options,  // 密码块的设置选项
                                  keyBytes, // 秘钥的字节
                                  keyLength, // 秘钥的长度
                                  ivDataBytes, // 可选初始化向量的字节
                                  dataBytes, // 加解密内容的字节
                                  dataLength, // 加解密内容的长度
                                  cryptPointer, // output data buffer
                                  cryptLength,  // output data length available
                                  &numBytesCrypted); // real output data length
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData!.length = Int(numBytesCrypted);
            if op == 1  {
                // 返回加密的数据
                let hexStr = DataUtils.nsDataToHex(data: cryptData!);
                return hexStr;
            } else {
                // 返回解密的数据
                let hexStr = DataUtils.nsDataToHex(data: cryptData!);
                return hexStr;
            }
        }
        return nil;
    }
二、问题解决

重新看了一遍android加密调用部分的代码,使用了十六进制字符串转byte数组的方法:
【ios】【android】3DES_CBC_PKCS5Padding加密、解密问题(附完整代码)
由于是对蓝牙数据进行加密,所以传入的字符串为十六进制,在ios代码中使用:

(content as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData;

是错误的,改为十六进制字符串的转换方法:

let keyData: NSData = Data.init(hex: key) as NSData;

最终获取到了正确的加密结果。

问题二:解密结果不一致

一、问题描述

在解决完加密结果不一致的问题后,发现ios的解密结果也与android结果不一致。

二、问题解决

在着手解决加密结果不一致的问题时,有篇文章中写到android对key的处理,若key为16字节,则会将前8字节拼接到key末尾,组成24字节的key,而ios存在16字节与24字节两种长度的key值,若传入的key为16字节,则会直接使用16字节的key。所以在key传入时,对其做长度的判断,若为16字节则进行拼接即可解决。文章来源地址https://www.toymoban.com/news/detail-417236.html

ios部分代码如下:
	public static func decryptionCBC(key: String, iv: String, content: String) -> String? {
        // 密钥处理
        var keyStr = [String]();
        if key.length() == 32 {
            keyStr.append(key);
            keyStr.append(key.substr(index: 0, length: 16));
        }
        let keyData: NSData = Data.init(hex: keyStr.joined()) as NSData;
        let keyBytes = UnsafeRawPointer(keyData.bytes);
        let keyLength = size_t(kCCKeySize3DES);
        // 可选的初始化向量
        let ivData: NSData = Data.init(hex: iv) as NSData;
        let ivDataBytes = UnsafeRawPointer(ivData.bytes);
        // 加密或解密的内容
        let ccop = CCOperation(kCCDecrypt);
        let data = Data.init(hex: content) as NSData;
        let dataLength = size_t(data.length);
        let dataBytes = UnsafeRawPointer(data.bytes);
        // 返回数据
        let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES);
        let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes);
        let cryptLength = size_t(cryptData!.length);
        // 特定的几个参数
        let operation: CCOperation = UInt32(ccop);
        let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES);
        let options: CCOptions = UInt32(kCCOptionPKCS7Padding);
        var numBytesCrypted :size_t = 0;
        let cryptStatus = CCCrypt(operation, // 加密还是解密
                                  algoritm, // 算法类型
                                  options,  // 密码块的设置选项
                                  keyBytes, // 秘钥的字节
                                  keyLength, // 秘钥的长度
                                  ivDataBytes, // 可选初始化向量的字节
                                  dataBytes, // 加解密内容的字节
                                  dataLength, // 加解密内容的长度
                                  cryptPointer, // output data buffer
                                  cryptLength,  // output data length available
                                  &numBytesCrypted); // real output data length
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData!.length = Int(numBytesCrypted);
            let hexStr = DataUtils.nsDataToHex(data: cryptData!);
            return hexStr;
        }
        return nil;
    }

附一:测试通过后的IOS SWIFT 3DES加密解密代码

	/**
     - CBC算法加密
     - parameter key: 密钥
     - parameter iv: 偏移量
     - parameter content: 加密数据
     - returns: string
     */
    public static func encryptionCBC(key: String, iv: String, content: String) -> String? {
        // 密钥处理
        var keyStr = [String]();
        if key.length() == 32 {
            keyStr.append(key);
            keyStr.append(key.substr(index: 0, length: 16));
        }
        let keyData: NSData = Data.init(hex: keyStr.joined()) as NSData;
        let keyBytes = UnsafeRawPointer(keyData.bytes);
        let keyLength = size_t(kCCKeySize3DES);
        // 可选的初始化向量
        let ivData: NSData = Data.init(hex: iv) as NSData;
        let ivDataBytes = UnsafeRawPointer(ivData.bytes);
        // 加密或解密的内容
        let ccop = CCOperation(kCCEncrypt);
        let data = Data.init(hex: content) as NSData;
        let dataLength = size_t(data.length);
        let dataBytes = UnsafeRawPointer(data.bytes);
        // 返回数据
        let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES);
        let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes);
        let cryptLength = size_t(cryptData!.length);
        // 特定的几个参数
        let operation: CCOperation = UInt32(ccop);
        let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES);
        let options: CCOptions = UInt32(kCCOptionPKCS7Padding);
        var numBytesCrypted :size_t = 0;
        let cryptStatus = CCCrypt(operation, // 加密还是解密
                                  algoritm, // 算法类型
                                  options,  // 密码块的设置选项
                                  keyBytes, // 秘钥的字节
                                  keyLength, // 秘钥的长度
                                  ivDataBytes, // 可选初始化向量的字节
                                  dataBytes, // 加解密内容的字节
                                  dataLength, // 加解密内容的长度
                                  cryptPointer, // output data buffer
                                  cryptLength,  // output data length available
                                  &numBytesCrypted); // real output data length
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData!.length = Int(numBytesCrypted);
            let hexStr = DataUtils.nsDataToHex(data: cryptData!);
            return hexStr;
        }
        return nil;
    }

	/**
     - CBC算法解密
     - parameter key: 密钥
     - parameter iv: 偏移量
     - parameter content: 加密数据
     - returns: string
     */
    public static func decryptionCBC(key: String, iv: String, content: String) -> String? {
        // 密钥处理
        var keyStr = [String]();
        if key.length() == 32 {
            keyStr.append(key);
            keyStr.append(key.substr(index: 0, length: 16));
        }
        let keyData: NSData = Data.init(hex: keyStr.joined()) as NSData;
        let keyBytes = UnsafeRawPointer(keyData.bytes);
        let keyLength = size_t(kCCKeySize3DES);
        // 可选的初始化向量
        let ivData: NSData = Data.init(hex: iv) as NSData;
        let ivDataBytes = UnsafeRawPointer(ivData.bytes);
        // 加密或解密的内容
        let ccop = CCOperation(kCCDecrypt);
        let data = Data.init(hex: content) as NSData;
        let dataLength = size_t(data.length);
        let dataBytes = UnsafeRawPointer(data.bytes);
        // 返回数据
        let cryptData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES);
        let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes);
        let cryptLength = size_t(cryptData!.length);
        // 特定的几个参数
        let operation: CCOperation = UInt32(ccop);
        let algoritm: CCAlgorithm = UInt32(kCCAlgorithm3DES);
        let options: CCOptions = UInt32(kCCOptionPKCS7Padding);
        var numBytesCrypted :size_t = 0;
        let cryptStatus = CCCrypt(operation, // 加密还是解密
                                  algoritm, // 算法类型
                                  options,  // 密码块的设置选项
                                  keyBytes, // 秘钥的字节
                                  keyLength, // 秘钥的长度
                                  ivDataBytes, // 可选初始化向量的字节
                                  dataBytes, // 加解密内容的字节
                                  dataLength, // 加解密内容的长度
                                  cryptPointer, // output data buffer
                                  cryptLength,  // output data length available
                                  &numBytesCrypted); // real output data length
        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData!.length = Int(numBytesCrypted);
            let hexStr = DataUtils.nsDataToHex(data: cryptData!);
            return hexStr;
        }
        return nil;
    }

附二:测试通过后的ANDROID 3DES加密解密代码

一、Des3Utils.java
	/**
     * CBC算法加密
     *
     * @param key
     * @param content
     * @return
     */
    public static String encryptionCBC(String key, String iv, String content) {
        Des3EncryptUtils des = new Des3EncryptUtils();
        byte[] bye = des.get3DesEncCodeCBC(DataUtils.hexStrToByteArray(content), DataUtils.hexStrToByteArray(key), DataUtils.hexStrToByteArray(iv));
        return HexUtils.toString(bye).trim();
    }

	/**
     * CBC算法解密
     *
     * @param key
     * @param content
     * @return
     */
    public static byte[] decryptionCBC(String key, String iv, String content) {
        Des3EncryptUtils des = new Des3EncryptUtils();
        return des.get3DesDesCodeCBC(DataUtils.hexStrToByteArray(content), DataUtils.hexStrToByteArray(key), DataUtils.hexStrToByteArray(iv));
    }
二、DataUtils.java
	/**
     * 16进制字符串转byte数组
     *
     * @param hexStr
     * @return
     */
    public static byte[] hexStrToByteArray(String hexStr) {
        if (hexStr == null) {
            return null;
        }
        if (hexStr.length() == 0) {
            return new byte[0];
        }
        byte[] byteArray = new byte[hexStr.length() / 2];
        for (int i = 0; i < byteArray.length; i++) {
            String subStr = hexStr.substring(2 * i, 2 * i + 2);
            byteArray[i] = ((byte) Integer.parseInt(subStr, 16));
        }
        return byteArray;
    }
三、Des3EncryptUtils.java
    /**
     * CBC算法加密(带向量)
     *
     * @param byteS
     * @return
     */
    public byte[] get3DesEncCodeCBC(byte[] byteS, byte[] key, byte[] iv) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
            SecretKey desKey = new SecretKeySpec(key, "DESede");
            IvParameterSpec desIV = new IvParameterSpec(iv);
            cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            cipher.init(cipher.ENCRYPT_MODE, desKey, desIV);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception error) {
            error.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }

    /**
     * CBC算法解密(带向量)
     *
     * @param byteS
     * @return
     */
    public byte[] get3DesDesCodeCBC(byte[] byteS, byte[] key, byte[] iv) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
            SecretKey desKey = new SecretKeySpec(key, "DESede");
            IvParameterSpec desIV = new IvParameterSpec(iv);
            cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            cipher.init(cipher.DECRYPT_MODE, desKey, desIV);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception error) {
            error.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }

到了这里,关于【ios】【android】3DES_CBC_PKCS5Padding加密、解密问题(附完整代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ssh命令报错no matching cipher found. Their offer: aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc

    执行 ssh user@host 报错,信息如下: 协议不匹配 可以使用如下命令 ssh -c aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc user@host 也可以修改 ~/.ssh/config文件 vi ~/.ssh/config 增加配置 Ciphers +aes128-cbc,aes192-cbc,aes256-cbc

    2024年02月13日
    浏览(34)
  • JAVA加密解密异常之java.security.NoSuchAlgorithmException: Cannot find any provider supporting DES/CBC/PKCS7

    AVA加密解密异常之java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CBC/PKCS7Padding 网上最接近的解决办法: 最后解决办法: 1.在jdk中的jrelibsecurity修改java.security文件,替换security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider。 并将原有的#security.provider.7=com.sun.s

    2024年02月03日
    浏览(36)
  • 关于Triple DES(3DES)对称加密算法

    一、引言 在网络安全领域,对称加密算法作为一种常见的加密手段,被广泛应用于保障数据传输的保密性和完整性。其中,DES(Data Encryption Standard)算法作为一种经典的对称加密算法,由IBM于1970年代开发,并于1977年被美国国家标准与技术研究院(NIST)确定为联邦信息处理标

    2024年02月04日
    浏览(44)
  • PHP 3DES加密

    不多说,直接上代码类 然后自行依据实际情况调用即可 自行了解引用,有测试示例在代码中 1. 2. 3. 4. 5. 6. 7.

    2024年02月13日
    浏览(41)
  • go语言对称加密使用(DES、3DES、AES)

    进行DES、3DES、AES三种对称加密算法时,首先要对原始数据进行字节填充,使原始数据位数与所对应加密算法块数据量成倍数。 block cipher(分组密码、块密码) block size(块大小) DEA、3DES的block size为8位 AES的block size为16位 每个填充的字节都记录了填充的总字节数 \\\"a\\\" 填充后:

    2024年02月08日
    浏览(33)
  • 3DES实验 思考与练习:

    T1:关于3DES的分析 和 库函数的思考——完全领悟了!!! 分析过程: T(2): 使用openssl库函数 实现 DES加密: 使用函数DES_ecb_encrypt来进行数据加解密 void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output, DES_key_schedule *ks,int enc); 函数功能说明:DES ECB计算 参数说明: input: 输入数据;

    2024年02月03日
    浏览(30)
  • 【密码算法 之一】对称加密算法 DES \ 3DES 浅析

      DES(Data Encryption Standard)是1977年美国联邦信息处理标准(FIPS)中所采用的一种对称密码(FIPS 46-3)。DES一直以来被美国以及其它国家的政府和银行等广泛使用。   然而,随着计算机的进步,现在DES已经能够被暴力破解,强度大不如从前了。20世纪末,RSA公司举办过破

    2024年02月09日
    浏览(45)
  • 密码学之DES,3DES与Python实现AES

    最近项目中需要用到DES,3DES解密算法,所以了解一下。正好CSDN上有关于DES,3DES的资料。边看边写一下总结。 密码学之DES,3DES详解与Python实现 DES(Data Encryption Standard-数据加密标准)属于对称加密,即使用相同的密钥来完成加密和解密。分组长度为8个字节64bit(密钥每个字节的最

    2024年02月08日
    浏览(25)
  • Java 中常见的加密算法,DES、3DES、AES、RSA

    加密算法是一种将数据转换为不可读形式的算法,以保护数据的机密性和完整性。加密算法被广泛应用于计算机网络、数据库、电子商务等领域,用于保护敏感数据的安全性,如用户密码、信用卡信息、医疗记录等。在 Java 中,有许多常见的加密算法,本文将对加密算法的基

    2024年02月03日
    浏览(43)
  • JavaScript学习 -- 对称加密算法3DES

    在现代的互联网时代,数据安全性备受关注。为了保护敏感数据的机密性,对称加密算法是一种常用的方法。在JavaScript中,3DES(Triple Data Encryption Standard)是一种常用的对称加密算法。本篇博客将为您展示如何在JavaScript中使用3DES算法进行加密和解密,并提供一个实际的例子

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包