iOS Android DES加解密一致性问题
iOS DES 加解密
// 加密方法
+ (NSData *)DESEncrypt:(NSData *)data WithKey:(NSString *)key
{
//DES密钥参与运算的只有64位,超出的部分并不参与加密运算 可参考 https://www.cnblogs.com/songwenlong/p/5944139.html
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
NSData *keybyte = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t numBytesEncrypted = 0;
// ios中填写的参数比较多,android中有些参数在cipher中默认了
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding,
keyPtr, kCCBlockSizeDES,
[keybyte bytes],
[data bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
// 解密方法
+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key
{
char keyPtr[kCCKeySizeAES256+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
NSData *keybyte = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
kCCOptionPKCS7Padding,
keyPtr, kCCBlockSizeDES,
[keybyte bytes],
[data bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
Android DES加解密
// 加密
public static String encode(String key, byte[] data) throws Exception {
try {
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
AlgorithmParameterSpec paramSpec = iv;
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] bytes = cipher.doFinal(data);
// return byte2hex(bytes);
return new String(Base64.encode(bytes));
} catch (Exception e) {
throw new Exception(e);
}
}
//解密
public static byte[] decode(String key, byte[] data) throws Exception {
try {
SecureRandom sr = new SecureRandom();
DESKeySpec dks = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// key的长度不能够小于8位字节
Key secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
AlgorithmParameterSpec paramSpec = iv;
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(data);
} catch (Exception e) {
throw new Exception(e);
}
}
iOS中支持的填充只有两种模式
/*!
@enum CCOptions
@abstract Options flags, passed to CCCryptorCreate().
@constant kCCOptionPKCS7Padding Perform PKCS7 padding.
@constant kCCOptionECBMode Electronic Code Book Mode.
Default is CBC.
*/
enum {
/* options for block ciphers */
kCCOptionPKCS7Padding = 0x0001,
kCCOptionECBMode = 0x0002
/* stream ciphers currently have no options */
};
typedef uint32_t CCOptions;
注意:
⚠️ EBC 填充模式是不需要填写iv向量的,而kCCOptionPKCS7Padding 是需要填写iv 值的
⚠️iOS中没有PKCS5Padding 填充模式
- java 中 "DES/CBC/PKCS5Padding" 对应的Object-C的是 kCCOptionPKCS7Padding
- java中 "DES/ECB/PKCS5Padding" 对应的Object-C的是 kCCOptionPKCS7Padding | kCCOptionECBMod
参考文章:
网友评论