使用Objective-C加密数据并使用Java Problem解密 [英] Encrypting data with Objective-C and decrypt it with Java Problem

查看:115
本文介绍了使用Objective-C加密数据并使用Java Problem解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an iPhone solutions that uses XML to transmit data between the client (mobile) and the server (Java). Some of the parts of the message (XML) must be encrypted because of the type of information transmitted. I planned to use AES 128 to encrypt and decrypt the data between these two endpoints.

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

First the sensitive data is encrypted using Object-C's CommonCrypto framework, and then the data is decrypted inside a Java Server (Servlet).

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

I'm new to security protocols and standards, and basically my code is a subset of group of informations that I could gather on Apple's dev forum/resources, and the internet (Google) :-)

基本流程为:


  1. 数据使用AES加密(使用pre -set key)。

  2. 加密字节放在XML中(使用base64)

  3. 数据从XML收集,并使用解密相同的预设密钥;

Object-C代码的加密部分是:

The encryption part of the Object-C code is:

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代码部分是:

The Java code part is:

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中运行上述解决方案时出现的错误是:

The error I get when running these solution above in the Java Server is:

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)

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

I know that the full stack wasn't needed, but anyways...

提前很多。

Joao

推荐答案

此代码适用于我。看看:

This code works for me. Give a look:

AES 128 IOS

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

I found the Base64 class here: http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php

希望它可以帮助某人

这篇关于使用Objective-C加密数据并使用Java Problem解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆