使用Objective-C加密数据并使用Java Problem解密

我有一个iPhone解决方案,它使用XML在客户端(移动)和服务器(Java)之间传输数据。 由于传输的信息类型,必须加密消息的某些部分(XML)。 我计划使用AES 128来加密和解密这两个端点之间的数据。

首先使用Object-C的CommonCrypto框架加密敏感数据,然后在Java Server(Servlet)内解密数据。

我是安全协议和标准的新手,基本上我的代码是我可以在Apple的开发论坛/资源和互联网(Google)上收集的一组信息的子集:-)

基本流程是:

  1. 使用AES(使用预设密钥)对数据进行加密。
  2. 加密的字节放在XML中(使用base64)
  3. 数据从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 Server中运行上述解决方案时遇到的错误是:

 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) 

我知道不需要完整的堆栈,但无论如何……

提前多了。

若昂

这段代码适合我。 看看:

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]]; } 

JAVA

 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

希望它可以帮助某人