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);
(检索填充的加密字符串时)
希望这可以帮助人们解决同样的问题...
我正在尝试将 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);
(检索填充的加密字符串时)
希望这可以帮助人们解决同样的问题...