问题一:加密结果不一致
一、问题描述
实现了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代码中使用:
(content as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData;
是错误的,改为十六进制字符串的转换方法:
let keyData: NSData = Data.init(hex: key) as NSData;
最终获取到了正确的加密结果。
问题二:解密结果不一致
一、问题描述
在解决完加密结果不一致的问题后,发现ios的解密结果也与android结果不一致。文章来源:https://www.toymoban.com/news/detail-417236.html
二、问题解决
在着手解决加密结果不一致的问题时,有篇文章中写到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模板网!