我有一个 iPhone 解决方案,它使用 XML 在客户端(移动设备)和服务器(Java)之间传输数据。由于传输的信息类型,消息 (XML) 的某些部分必须加密。我计划使用 AES 128 来加密和解密这两个端点之间的数据。
首先使用 Object-C 的 CommonCrypto 框架对敏感数据进行加密,然后在 Java 服务器 (Servlet) 中对数据进行解密。
我是安全协议和标准的新手,基本上我的代码是我可以在 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 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)
我知道不需要完整的堆栈,但无论如何......
提前多谢。
若昂