iOS,java ee:aes加密,发送后更改字节
我试图将aes加密数据发送到javaee服务器,并在发送后获得不同的字节。当我在ios和javaee上用相同的密钥加密相同的字符串时,我得到的字节是相同的,但是当我将加密的字节发送到服务器时,它们会稍微偏离。这是我的加密方法 *****iOS AES加密*****iOS,java ee:aes加密,发送后更改字节,java,ios,jakarta-ee,encryption,aes,Java,Ios,Jakarta Ee,Encryption,Aes,我试图将aes加密数据发送到javaee服务器,并在发送后获得不同的字节。当我在ios和javaee上用相同的密钥加密相同的字符串时,我得到的字节是相同的,但是当我将加密的字节发送到服务器时,它们会稍微偏离。这是我的加密方法 *****iOS AES加密***** - (NSData*)AES256EncryptWithKey:(NSString*)key { char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unus
- (NSData*)AES256EncryptWithKey:(NSString*)key {
char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding/*NSUTF8StringEncoding*/];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
{
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
这是NSData的“添加”示例。所以我的实现是
NSData *encryptedData = [self encryptString:@"test" withKey:@"0123456789abcdef"];
byte[] encryptedString = AESencrypt("test", "0123456789abcdef");
其中“encryptString:withKey:”是
- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
}
这是返回字节
(d24374ca 9c7adedd 26d3d285 8d42e69c)
然后,我将其设置为url请求的主体
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://myurl.com"]];
[request setHTTPBody:encryptedData];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSURLResponse *response;
NSError *errro;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&errro];
我的java aes加密方法是
public byte[] AESencrypt(String plainText, String encryptionKey) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES");
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, key,ivParameterSpec/*new IvParameterSpec(INITIALIZATIO_VECTOR.getBytes("UTF-8"))*/);
return cipher.doFinal(plainText.getBytes("UTF-8"));
}
我的实现是
NSData *encryptedData = [self encryptString:@"test" withKey:@"0123456789abcdef"];
byte[] encryptedString = AESencrypt("test", "0123456789abcdef");
结果是(d24374ca 9c7adedd 26d3d285 8d42e69c)
与iphone版本相同
但是当我在javaee中检索url请求的主体时,得到的字节略有不同。我获取字节的方式是这样的
*这是通过doGet方法完成的*
BufferedReader reader = request.getReader();
body = reader.readLine();
byte[] bytes = body.getBytes();
然后当我打印出字节时,我得到D24374CA3F7ADEDD26D3D23F42E63F。。。(与iPhone和javaee不同)
因此,概括一下
iPhone AES加密字节:d24374ca 9c7adedd 26d3d285 8d42e69c
javaee加密字节:d24374ca 9c7adedd 26d3d285 8d42e69c
传输字节:d24374ca 3f7adedd 26d3d23f 3f42e63f
当我将字节发送到javaee服务器时,这些字节会被更改,这是我做错了什么
谢谢你的帮助
*更新*
BufferedReader reader = request.getReader();
body = reader.readLine();
byte[] bytes = body.getBytes();
我一直在搞乱它,注意到当我从ios加密中删除“+1”时(在第二行),字节在到达服务器时不会改变。。。但是结果是不同的,我似乎不能在服务器端得到相同的结果:/。。。。也许这会有所帮助?终于强> 我找到了答案!!所以我加密的方法是正确的,问题是获取请求的主体 在我做之前
BufferedReader reader = request.getReader();
body = reader.readLine();
byte[] bytes = body.getBytes();
使用“getReader()”是导致问题的原因。所以我用了这个代码来代替上面的代码
InputStream is = request.getInputStream();
byte[] bytes = getBytesFromInputStream(is);
其中“getBytesFromInputStream”是
public static byte[] getBytesFromInputStream(InputStream is) throws IOException
{
try (ByteArrayOutputStream os = new ByteArrayOutputStream();)
{
byte[] buffer = new byte[0xFFFF];
for (int len; (len = is.read(buffer)) != -1;)
os.write(buffer, 0, len);
os.flush();
return os.toByteArray();
}
}
从那里我得到了与发送到服务器相同的字节。我想我在某个地方读到“getReader()”改变了一些填充字符或其他东西,我想这就是为什么当我去掉“+1”时,字节不会改变
总之
不要使用
BufferedReader reader = request.getReader();
body = reader.readLine();
byte[] bytes = body.getBytes();
改用
InputStream is = request.getInputStream();
byte[] bytes = getBytesFromInputStream(is);
(检索填充加密字符串时)
希望这能帮助人们解决同样的问题……使用硬编码静脉输液会违背CBC的目的,让你容易受到伤害。如果有人想知道,这对返回加密数据是正确的。不要使用response.getWriter()而是使用response.getOutputStream()