iOS, java ee: aes加密,发送后字节变化

iOS, java ee: aes encryption, bytes changing after being send

我正在尝试将 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 的 'AESAdditions' 示例。所以我的实现是...

NSData *encryptedData = [self encryptString:@"test" withKey:@"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"));

  }

我的实现是...

byte[] encryptedString = AESencrypt("test", "0123456789abcdef");

结果是 (d24374ca 9c7adedd 26d3d285 8d42e69c) 与 iphone 版本相同...

但是当我在 javaee 中检索 url 请求的正文时,我得到的字节略有不同。我获取字节的方式是这样的...

* 这是在 doGet 方法中完成的 *

BufferedReader reader = request.getReader();    

body = reader.readLine();
byte[] bytes = body.getBytes();

然后当我打印出字节时,我得到 d24374ca 3f7adedd 26d3d23f 3f42e63f ...(不同于 iPhone 和 javaee)

所以回顾一下...

iPhone AES 加密字节:d24374ca 9c7adedd 26d3d285 8d42e69c

javaee 加密字节:d24374ca 9c7adedd 26d3d285 8d42e69c

传输字节:d24374ca 3f7adedd 26d3d23f 3f42e63f

当我将字节发送到 javaee 服务器时,字节被更改,我做错了什么?

感谢您的帮助

* 更新 *

我一直在弄乱它并注意到当我从 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);

(检索填充的加密字符串时)

希望这可以帮助人们解决同样的问题...