Шифрование данных с помощью Objective-C и дешифрование с помощью Java.
У меня есть решения для iPhone, которые используют XML для передачи данных между клиентом (мобильным) и сервером (Java). Некоторые части сообщения (XML) должны быть зашифрованы из-за типа передаваемой информации. Я планировал использовать AES 128 для шифрования и дешифрования данных между этими двумя конечными точками.
Сначала конфиденциальные данные шифруются с использованием инфраструктуры CommonCrypto Object-C, а затем данные дешифруются внутри Java-сервера (сервлета).
Я новичок в области протоколов и стандартов безопасности, и в основном мой код представляет собой подмножество групп информации, которую я мог бы собрать на форуме / ресурсах Apple для разработчиков и в Интернете (Google):-)
Основной поток:
- Данные зашифрованы с использованием AES (с использованием предварительно установленного ключа).
- Зашифрованные байты помещаются в XML (используя base64)
- Данные собираются из XML и расшифровываются с использованием того же предварительно установленного ключа;
Часть шифрования кода Object-C:
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) {
...
}
Ошибка, которую я получаю при запуске этих решений выше на сервере Java:
15:57:43,671 ERROR [STDERR] com.iteatros.aim.services.ServiceException: javax.crypto.BadPaddingException: pad block corrupted
15:57:43,674 ERROR [STDERR] at com.iteatros.aim.services.security.SecurityWrapper.decrypt3DESBase64StringData(SecurityWrapper.java:109)
15:57:43,674 ERROR [STDERR] at com.iteatros.aim.services.db.LoginDAO.login(LoginDAO.java:53)
15:57:43,674 ERROR [STDERR] at com.iteatros.aim.services.AbstractService.authenticate(AbstractService.java:278)
15:57:43,674 ERROR [STDERR] at com.iteatros.aim.services.AbstractService.doPost(AbstractService.java:165)
15:57:43,674 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
15:57:43,674 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
15:57:43,674 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
15:57:43,675 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
15:57:43,675 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
15:57:43,675 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
15:57:43,676 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
15:57:43,676 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
15:57:43,676 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
15:57:43,676 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
15:57:43,676 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
15:57:43,676 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
15:57:43,676 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
15:57:43,677 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
15:57:43,677 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
15:57:43,677 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
15:57:43,677 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
15:57:43,677 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
15:57:43,677 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
15:57:43,677 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
15:57:43,677 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
15:57:43,677 ERROR [STDERR] at java.lang.Thread.run(Thread.java:680)
Я знаю, что полный стек не был нужен, но в любом случае...
Спасибо большое заранее.
Joao
1 ответ
Этот код работает для меня. Посмотрите:
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]];
}
ДЖАВА
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();
}
}
Я нашел класс Base64 здесь: http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php
Надеюсь, что это может помочь кому-то