iOS,java ee: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

我试图将aes加密数据发送到javaee服务器,并在发送后获得不同的字节。当我在ios和javaee上用相同的密钥加密相同的字符串时,我得到的字节是相同的,但是当我将加密的字节发送到服务器时,它们会稍微偏离。这是我的加密方法

*****iOS AES加密*****

 - (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()