DES加密值不匹配android和ios

时间:2015-06-18 07:07:26

标签: ios objective-c iphone encryption

IOS代码

#import "DESCodec.h"
#import <CommonCrypto/CommonCryptor.h>


@implementation DESCodec
{
 NSString *key;
}

-(id) init{
self=[super init];
if(self){
    key=@"12345678";
}
return self;
}

-(NSString *) decode:(NSString *)encoded{
    NSData *inputData = [[NSData alloc] initWithBase64EncodedString:encoded options:0];
    NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
    size_t outLength;

    NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  + 

 kCCBlockSizeDES)];

CCCryptorStatus
result = CCCrypt(kCCDecrypt, // operation
                 kCCAlgorithmDES, // Algorithm
                 kCCOptionPKCS7Padding , // options
                 keyData.bytes, // key
                 keyData.length, // keylength
                 nil,// iv
                 inputData.bytes, // dataIn
                 inputData.length, // dataInLength,
                 outputData.mutableBytes, // dataOut
                 outputData.length, // dataOutAvailable
                 &outLength); // dataOutMoved

if (result != kCCSuccess) {
    return nil;
}
[outputData setLength:outLength];
return [[NSString alloc] initWithData:outputData `encoding:NSUTF8StringEncoding];`
}


-(NSString *) encode:(NSString *)decoded{

NSData *inputData = [decoded dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
size_t outLength;

NSMutableData *outputData = [NSMutableData dataWithLength:(inputData.length  +  kCCBlockSizeDES)];

CCCryptorStatus result = CCCrypt(kCCEncrypt, // operation
                                 kCCAlgorithmDES, // Algorithm
                                 kCCOptionPKCS7Padding, // options
                                 keyData.bytes, // key
                                 keyData.length, // keylength
                                 nil,// iv
                                 inputData.bytes, // dataIn
                                 inputData.length, // dataInLength,
                                 outputData.mutableBytes, // dataOut
                                 outputData.length, // dataOutAvailable
                                 &outLength); // dataOutMoved

if (result != kCCSuccess) {
    return nil;
}
[outputData setLength:outLength];
NSString *r = [outputData base64EncodedStringWithOptions:0];


    return r;
}

@end

DESCodec *codec=[[DESCodec alloc] init];
NSString *encoded=[codec encode:@"12345678"];
NSString decoded=[codec decode:encoded];
NSLog(@" %@ %@",encoded,decoded);

值为ltACiHjVjImOJQ1fTHZkSw ==和12345678

但在java中,encypted text是&#34; ltACiHjVjIn + uVm31GQvyw ==&#34;

我对目标C不满意,但我无法解决问题。

任何人都可以帮助我。谢谢和问候

Java代码

public class DESCodec {

    /**
     * Secret key that shall be used for encryption and decryption.
     */
    private String strSecretKey = "12345678";

    private static final String UNICODE_FORMAT = "UTF-8";

    private static final String DES_ENCRYPTION_SCHEME = "DES";

    private static final String TAG = "DESCodec";

    private Cipher cipher;

    private SecretKey key;


    public DESCodec() {
        try {
            this.strSecretKey = strSecretKey;
            String myEncryptionScheme = DES_ENCRYPTION_SCHEME;
            byte[] keyAsBytes = strSecretKey.getBytes(UNICODE_FORMAT);
            DESKeySpec myKeySpec = new DESKeySpec(keyAsBytes);
            SecretKeyFactory mySecretKeyFactory = SecretKeyFactory.getInstance(myEncryptionScheme);
            cipher = Cipher.getInstance(myEncryptionScheme);
            key = mySecretKeyFactory.generateSecret(myKeySpec);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    public String desEncrypt(String message) {
        String encryptedString = null;
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] plainText = message.getBytes(UNICODE_FORMAT);
            byte[] encryptedText = cipher.doFinal(plainText);

            encryptedString = Base64.encodeToString(encryptedText, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return encryptedString;
    }

    public String desDecrypt(String message) {
        String decryptedText = null;
        try {
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] encryptedText = Base64.decode(message, Base64.DEFAULT);
            byte[] plainText = cipher.doFinal(encryptedText);
            decryptedText = bytes2String(plainText);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptedText;
    }

    private String bytes2String(byte[] bytes) {
        try {
            return new String(bytes, UNICODE_FORMAT);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

2 个答案:

答案 0 :(得分:3)

这显然只是操作模式的问题,因为第一个块匹配。在Java中,您使用的是ECB模式,因为“DES”默认为“DES / ECB / PKCS5Padding”。我认为CCCryptor默认为CBC。

不要使用ECB模式。它在语义上不安全。您需要至少使用随机IV的CBC模式。 IV不必是秘密的,因此您可以将其添加到密文中。请查看具有其他安全功能的RNCryptor,例如密文验证。它还有一个Java实现。

不要再使用DES了。它不再安全了。你应该使用AES。三重DES也不是那么糟糕。

答案 1 :(得分:0)

当我开发iOS应用程序时,我遇到了同样的问题。许多人都使用了android客户端,因此我无法将算法更改为AES或其他。如Artjom B.在Java中说'DES'默认为'DES / ECB / PKCS5Padding',在源代码中你可以找到

Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");

但不幸的是在iOS中你只是找到了

enum {
    kCCOptionPKCS7Padding = 0x0001,
    kCCOptionECBMode      = 0x0002
}

但最后我找到了这样的解决方案

CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                              kCCAlgorithmDES,
                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                              [key UTF8String],
                              kCCKeySizeDES,
                              nil,
                              [cipherData bytes],
                              [cipherData length],
                              buffer,
                              1024,
                              &numBytesDecrypted);

重要性是kCCOptionPKCS7Padding | kCCOptionECBMode,你可以尝试这种方法。