美文网首页ios 开发
iOS Android DES加解密一致性问题

iOS Android DES加解密一致性问题

作者: 小乙的乙 | 来源:发表于2019-04-24 10:31 被阅读0次

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

代码DEMO

参考文章:

  1. https://www.cnblogs.com/LQCQ-Silent/p/5926584.html
  2. https://www.tuicool.com/articles/UJJrAj

相关文章

网友评论

    本文标题:iOS Android DES加解密一致性问题

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