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

用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加密(使用

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

首先使用Object-C的CommonCrypto框架对敏感数据进行加密,然后在Java服务器(Servlet)中对数据进行解密

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

基本流程是:

  • 数据使用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) {
        ...
    }
    
    我知道不需要整堆,但无论如何

    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();
            }
    
        }