DES在iOS、Android、Java加解密一致

前言:

移动客户端开发的时候往往涉及到数据加密,除开 HTTPS 之外,可以使用 DES\AES 加密了。然后在进行 base64编码进行数据传输。下文根据自己项目的实际经验编写。

1、Java服务端,android 提交过来的代码会把+号替换成空格,如果需要进行一次替换。

        public static String decrypt(String content, String password)
			throws Exception {
		return isEmpty(content) ? null : new String(decrypt(
				base64Decode(content), password), "utf-8");
	}

	public static byte[] decrypt(byte[] src, String password) throws Exception {
		// DES算法要求有一个可信任的随机数源
		SecureRandom random = new SecureRandom();
		// 创建一个DESKeySpec对象
		DESKeySpec desKey = new DESKeySpec(password.getBytes());
		// 创建一个密匙工厂
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		// 将DESKeySpec对象转换成SecretKey对象
		SecretKey securekey = keyFactory.generateSecret(desKey);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance("DES");
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, random);
		// 真正开始解密操作
		return cipher.doFinal(src);
	}

2、Android 端,基本和服务端基本一致。

 

    public static String desCrypto(String content, String password) {
    	 try {
			return base64Encode(desCrypto(content.getBytes("utf-8"), password));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} 
    	 return null;
    }
	public static byte[] desCrypto(byte[] datasource, String password) {              
        try{  
        SecureRandom random = new SecureRandom();  
        DESKeySpec desKey = new DESKeySpec(password.getBytes());  
        //创建一个密匙工厂,然后用它把DESKeySpec转换成  
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");  
        SecretKey securekey = keyFactory.generateSecret(desKey);  
        //Cipher对象实际完成加密操作  
        Cipher cipher = Cipher.getInstance("DES");  
        //用密匙初始化Cipher对象  
        cipher.init(Cipher.ENCRYPT_MODE, securekey, random);  
        //现在,获取数据并加密  
        //正式执行加密操作  
        return cipher.doFinal(datasource);  
        }catch(Throwable e){  
                e.printStackTrace();  
        }  
        return null;  
}

3、IOS 端

#pragma 加密算法
+(NSString *) encryptUseDES:(NSString *)plainText
{
	NSString *ciphertext = nil;
	NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
	NSUInteger dataLength = [textData length];
	unsigned char buffer[dataLength*10];
	memset(buffer, 0, sizeof(char));
	size_t numBytesEncrypted = 0;
	CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
										  kCCOptionPKCS7Padding | kCCOptionECBMode,
										  [passwd UTF8String], kCCKeySizeDES,
										  nil,
										  [textData bytes], dataLength,
										  buffer, dataLength*10,
										  &numBytesEncrypted);
	if (cryptStatus == kCCSuccess) {
		NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
		
		NSLog(@"data lenght:%ld",data.length);
		ciphertext = [Base64 encode:data];
	}
	return ciphertext;
}

需要特别注意几点

1、kCCOptionECBMode模式不支持 IV向量。

2、如果需要用到 IV 向量,kCCOptionPKCS7Padding加密,请在 android、java 服务端设置统一的 IV 向量。

3、ios 端需要自己写 base64代码。IOS 提交的 DES-BASE64代码服务器会无法解密,需要对数据去除空格。

desstr = [desstr stringByReplacingOccurrencesOfString:@” “ withString:@””];

4、android 版本上 base64好像在较低的模拟器上也需要自己写。

解密代码正常即可。

One response on “DES在iOS、Android、Java加解密一致

  1. 刘勋

    iOS端解密的算法有Demo吗,困扰我一天了,总是解出nil

发表评论