用Objective-C加密数据并用Java解密
我有一个iPhone解决方案,它使用XML在客户端(移动设备)和服务器(Java)之间传输数据。由于传输的信息类型不同,消息(XML)的某些部分必须加密。我计划使用AES 128加密和解密这两个端点之间的数据 首先使用Object-C的CommonCrypto框架对敏感数据进行加密,然后在Java服务器(Servlet)中对数据进行解密 我不熟悉安全协议和标准,基本上我的代码是一组信息的子集,我可以在苹果的开发论坛/资源和互联网(谷歌)上收集这些信息:-) 基本流程是:用Objective-C加密数据并用Java解密,java,iphone,objective-c,security,jce,Java,Iphone,Objective C,Security,Jce,我有一个iPhone解决方案,它使用XML在客户端(移动设备)和服务器(Java)之间传输数据。由于传输的信息类型不同,消息(XML)的某些部分必须加密。我计划使用AES 128加密和解密这两个端点之间的数据 首先使用Object-C的CommonCrypto框架对敏感数据进行加密,然后在Java服务器(Servlet)中对数据进行解密 我不熟悉安全协议和标准,基本上我的代码是一组信息的子集,我可以在苹果的开发论坛/资源和互联网(谷歌)上收集这些信息:-) 基本流程是: 数据使用AES加密(使用
char keyPtr [ kCCKeySizeAES128 +1 ];
bzero( keyPtr, sizeof(keyPtr) );
// The secret key is masked for obvious reason, but you can use "12345678912345678912345678912345"
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
// Initialization vector; dummy in this case 0's.
uint8_t iv[ kCCBlockSizeAES128 ];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
/*
For block ciphers, the output size will always be less than or
equal to the input size plus the size of one block.
*/
size_t bufferSize = (dataLength + kCCBlockSizeAES128);
void *buffer = malloc(bufferSize);
memset(buffer, 0x0, bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
kCCOptionECBMode + kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
iv, [data bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
Java代码部分是:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] keyBytes = DES_KEY.getBytes(); //<== The same as above
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
try {
// Return the raw bytes
byte []data = Base64.decode(encryptedContent);
// Gets the Cipher...
final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
String resultString = new String(cipher.doFinal(data));
} catch (Exception ex) {
...
}
我知道不需要整堆,但无论如何
Thanx提前了很多时间
Joao这个代码适合我。看一看: AES 128 IOS
+ (NSString *) encrypt:(NSString *) dataToEncrypt withKey:(NSString*) key{
NSData *data = [dataToEncrypt dataUsingEncoding:NSUTF8StringEncoding];
NSData *mData = [key dataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionECBMode | kCCOptionPKCS7Padding,
[mData bytes],
[mData length],
nil,
[data bytes],
[data length],
NULL,
0,
&bytesNeeded);
if(kCCBufferTooSmall != ccStatus){
NSLog(@"Here it must return BUFFER TOO SMALL !!");
return nil;
}
// .....End
// Now i do the real Crypting
char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;
if(NULL == cypherBytes)
NSLog(@"cypherBytes NULL");
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionECBMode | kCCOptionPKCS7Padding,
[mData bytes],
[mData length],
nil,
[data bytes],
[data length],
cypherBytes,
bufferLength,
&bytesNeeded);
if(kCCSuccess != ccStatus){
NSLog(@"kCCSuccess NO!");
return nil;
}
return [Base64 encode:[NSData dataWithBytes:cypherBytes length:bufferLength]];
}
爪哇
我在这里找到了Base64类:
希望它能帮助别人这段代码适合我。看一看: AES 128 IOS
+ (NSString *) encrypt:(NSString *) dataToEncrypt withKey:(NSString*) key{
NSData *data = [dataToEncrypt dataUsingEncoding:NSUTF8StringEncoding];
NSData *mData = [key dataUsingEncoding:NSUTF8StringEncoding];
CCCryptorStatus ccStatus = kCCSuccess;
// Begin to calculate bytesNeeded....
size_t bytesNeeded = 0;
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionECBMode | kCCOptionPKCS7Padding,
[mData bytes],
[mData length],
nil,
[data bytes],
[data length],
NULL,
0,
&bytesNeeded);
if(kCCBufferTooSmall != ccStatus){
NSLog(@"Here it must return BUFFER TOO SMALL !!");
return nil;
}
// .....End
// Now i do the real Crypting
char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;
if(NULL == cypherBytes)
NSLog(@"cypherBytes NULL");
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES,
kCCOptionECBMode | kCCOptionPKCS7Padding,
[mData bytes],
[mData length],
nil,
[data bytes],
[data length],
cypherBytes,
bufferLength,
&bytesNeeded);
if(kCCSuccess != ccStatus){
NSLog(@"kCCSuccess NO!");
return nil;
}
return [Base64 encode:[NSData dataWithBytes:cypherBytes length:bufferLength]];
}
爪哇
我在这里找到了Base64类:
希望它能帮助某人为什么不通过SSL/TLS进行通信呢?我同意,对我来说,这似乎是https解决的问题……双重同意,如果您不需要临时存储数据,只需使用安全通道。感谢您的回复,实际上,在花了几个小时在这两个世界之间进行断言之后,我真的倾向于使用SSL。无论如何,我解决了这个问题。如果有人想知道怎么做,问题就出在Java方面。AES 128位的密钥大小必须正好为16字节。当我使用32字节的密钥时,Java试图将AES块大小映射到256位,而不是128位(如objective-c中定义的)。尽管看起来令人困惑,但在Java和Objective-C两部分中更改密钥大小解决了这个问题。另外,请远离ECB模式,因为它不是非常安全。为什么不通过SSL/TLS进行通信?我同意,对我来说,这似乎是https解决的问题…双重同意,如果您不需要临时存储数据,只需使用安全通道。感谢您的回复,实际上在花了几个小时在这两个世界之间进行断言之后,我真的很想去。无论如何,我解决了这个问题。如果有人想知道怎么做,问题就出在Java方面。AES 128位的密钥大小必须正好为16字节。当我使用32字节的密钥时,Java试图将AES块大小映射到256位,而不是128位(如objective-c中定义的)。尽管看起来令人困惑,但在Java和Objective-C两部分中更改密钥大小解决了这个问题。另外,请远离ECB模式,因为它不太安全。对我来说不起作用:java.security.nosuchalgorithException:找不到任何支持AES/ECB/PKCS7PaddingTry的提供程序,无法从AES/ECB/PKCS7PaddingTry切换到AES/ECB/PKCS5Padding@kinghomer你太棒了,谢谢你的解决方案,我从没想过欧洲央行和pkcs7可以合并在一起,但什么是“kCCOptionECBMode | kCCOptionPKCS7Padding”意思是?@kinghomer:您的iOS代码声明了一个错误-使用了未声明的标识符“Base64”。@JayprakashDubey我在这里找到了Base64类:对我不起作用:java.security.NoSuchAlgorithmException:找不到任何支持AES/ECB/PKCS7PaddingTry的提供程序,无法从AES/ECB/PKCS7Padding切换到AES/ECB/PKCS5Padding@kinghomer你太棒了,感谢您的解决方案,我从未想过ecb和pkcs7可以合并在一起,但“KCCOPionECBMode | KCCOPionPKCS7Padding”是什么意思?@kinghomer:iOS代码声明了一个错误-使用了未声明的标识符“Base64”。@JayprakashDubey我在这里找到了Base64类:
public static void encrypt_AES(String message){
Cipher ecipher;
try {
// generate secret key using DES algorithm
SecretKeySpec key = new SecretKeySpec(theKey.getBytes("UTF-8"), "AES");
ecipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
// initialize the ciphers with the given key
ecipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encrypted = ecipher.doFinal(message.getBytes("UTF-8"));
}catch (Exception e) {
//
e.printStackTrace();
}
}