ios java 通信_AES加密解密 -- iOS、Java之间的互相通信

本文介绍了如何使用AES加密实现iOS与Java之间的通信。通过设置相同的加密参数(如CBC模式,256位密钥长度,32位初始向量),克服Java对256位密钥支持的限制,确保两端能够正确加解密数据。提供了iOS和Java的加密解密代码示例,并验证了通信的可行性。
摘要由CSDN通过智能技术生成

简介:AES是一种对称加密方式,旨在取代DES成为广泛使用的标准。虽然语言不同,但是AES的算法是相同的。

关于AES的各种参数请参考下面文章(一定要认真阅读,不然就没办法按照自己的想法进行加密解密):AES加密 - iOS与Java的同步实现

思路:

先说一下我的想法,iOS端加密由Java解密,Java加密由iOS解密,加密模式采取CBC,密钥长度为256位,初始向量(相当于是加密解密规则)为32位,这个是要对应密钥长度的。

难点:

1、Java对于大于128bits的是不支持的,我们需要将JDK中的local_policy.jar US_export_policy.jar用这里的jar包替换掉,我的mac电脑,JDK路径是资源库/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/libsecurity

784c8ad9a77a?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

替换的jar包

这样Java才会支持256位的密钥加密。

2、iOS端的kKeySize改为kCCKeySizeAES256。

3、两端的key(加密解密规则)设置成32位字符串。

实现:

iOS端

AESCipher.h

@interface AESCipher : NSObject

NSString * aesEncryptString(NSString *content, NSString *key);

NSString * aesDecryptString(NSString *content, NSString *key);

NSData * aesEncryptData(NSData *data, NSData *key);

NSData * aesDecryptData(NSData *data, NSData *key);

@end

AESCipher.m

#import

NSString const *kInitVector = @"A-16-Byte-String";

size_t const kKeySize = kCCKeySizeAES256;

NSData * cipherOperation(NSData *contentData, NSData *keyData, CCOperation operation) {

NSUInteger dataLength = contentData.length;

void const *initVectorBytes = [kInitVector dataUsingEncoding:NSUTF8StringEncoding].bytes;

void const *contentBytes = contentData.bytes;

void const *keyBytes = keyData.bytes;

size_t operationSize = dataLength + kCCKeySizeAES256;

void *operationBytes = malloc(operationSize);

size_t actualOutSize = 0;

CCCryptorStatus cryptStatus = CCCrypt(operation,

kCCAlgorithmAES,

kCCOptionPKCS7Padding,

keyBytes,

kKeySize,

initVectorBytes,

contentBytes,

dataLength,

operationBytes,

operationSize,

&actualOutSize);

if (cryptStatus == kCCSuccess) {

return [NSData dataWithBytesNoCopy:operationBytes length:actualOutSize];

}

free(operationBytes);

return nil;

}

NSString * aesEncryptString(NSString *content, NSString *key) {

NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding];

NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];

NSData *encrptedData = aesEncryptData(contentData, keyData);

return [encrptedData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

}

NSString * aesDecryptString(NSString *content, NSString *key) {

NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];

NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];

NSData *decryptedData = aesDecryptData(contentData, keyData);

return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];

}

NSData * aesEncryptData(NSData *contentData, NSData *keyData) {

NSString *hint = [NSString stringWithFormat:@"The key size of AES-%lu should be %lu bytes!", kKeySize * 8, kKeySize];

NSCAssert(keyData.length == kKeySize, hint);

return cipherOperation(contentData, keyData, kCCEncrypt);

}

NSData * aesDecryptData(NSData *contentData, NSData *keyData) {

NSString *hint = [NSString stringWithFormat:@"The key size of AES-%lu should be %lu bytes!", kKeySize * 8, kKeySize];

NSCAssert(keyData.length == kKeySize, hint);

return cipherOperation(contentData, keyData, kCCDecrypt);

}

先自行测试一下:

NSString *plainText = @"战狼2";

//32位key,加解密规则

NSString *key = @"16-Bytes--String16-Bytes--String";

NSString *cipherText = aesEncryptString(plainText, key);

NSLog(@"%@", cipherText);

NSString *decryptedText = aesDecryptString(cipherText, key);

NSLog(@"%@", decryptedText);

测试结果:

2017-08-07 17:04:07.346 AES加解密[1936:131257] BOtqpCDe2AcRw2sbt4+F9w==

2017-08-07 17:04:07.348 AES加解密[1936:131257] 战狼2

Java端:

一定要记得导入javabase64-1.3.1

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.util.Base64;

import java.util.Base64.Decoder;

import java.util.Base64.Encoder;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.io.UnsupportedEncodingException;

public class AESCipher {

private static final String IV_STRING = "A-16-Byte-String";

private static final String charset = "UTF-8";

public static String aesEncryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

byte[] contentBytes = content.getBytes(charset);

byte[] keyBytes = key.getBytes(charset);

byte[] encryptedBytes = aesEncryptBytes(contentBytes, keyBytes);

Encoder encoder = Base64.getEncoder();

return encoder.encodeToString(encryptedBytes);

}

public static String aesDecryptString(String content, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

Decoder decoder = Base64.getDecoder();

byte[] encryptedBytes = decoder.decode(content);

byte[] keyBytes = key.getBytes(charset);

byte[] decryptedBytes = aesDecryptBytes(encryptedBytes, keyBytes);

return new String(decryptedBytes, charset);

}

public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE);

}

public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {

return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE);

}

private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");

byte[] initParam = IV_STRING.getBytes(charset);

IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(mode, secretKey, ivParameterSpec);

return cipher.doFinal(contentBytes);

}

}

测试:

String key = "16-Bytes--String16-Bytes--String";

String encryptStr = AESCipher.aesEncryptString("战狼2", key);

System.out.println(encryptStr);

String decryptStr = AESCipher.aesDecryptString(encryptStr, key);

System.out.println(decryptStr);

结果:

BOtqpCDe2AcRw2sbt4+F9w==

战狼2

两端之间的通信:

由上面测试结果可以看出,相同的加密规则,相同的加密内容,加密之后的结果是相同的。所以无论是iOS端加密,Java端解密 还是Java端加密,iOS端解密,都是可以实现的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值