加密为iOS 3DES不一样的Andr​​oid和.NET [英] Encryption for iOS 3des not same as android and .net

查看:419
本文介绍了加密为iOS 3DES不一样的Andr​​oid和.NET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要做的使用3DES上必须匹配Java和.NET的结果iOS的一些加密的东西。

的Java code为:

 公共类EncryptionHelper {

//加密字符串和连接code为Base64
公共静态字符串encryptText(明文字符串,字符串键,字符串IV)抛出异常{
    // ----使用指定的3DES密钥和IV从其他来源--------------
    byte []的明文= plainText.getBytes(); //输入
    byte []的tdesKeyData = key.getBytes(); //你的加密密钥

    byte []的myIV = IV.getBytes(); //初始化向量

    密c3des = Cipher.getInstance(DESede / CBC / PKCS5Padding);
    SecretKeySpec的myKey =新SecretKeySpec(tdesKeyData,DESede);
    IvParameterSpec ivspec =新IvParameterSpec(myIV);

    c3des.init(Cipher.ENCRYPT_MODE,的myKey,ivspec);
    byte []的密文= c3des.doFinal(明文);
    字符串encryptedString = Base64.en codeToString(密文,
            Base64.DEFAULT);
    //返回的Base64 coder.en codeString的(新的字符串(密文));
    返回encryptedString;
}
 

}

和iOS $ C $下同样是:

   - (的NSString *)new3DESwithoperand:(的NSString *)明文encryptOrDecrypt:(CCOperation)encryptorDecrypt键:(的NSString *)键initVec:(的NSString *)initVec
{

的NSData *数据= [明文data​​UsingEncoding:NSUTF8StringEncoding]。
常量无效* vplainText = [数据字节]。
为size_t plainTextBufferSize = [数据长度]
的NSLog(@%@,长度:%U,[数据说明],[数据长度]);

为size_t bufferPtrSize =(plainTextBufferSize + kCCBlockSize3DES)及〜(kCCBlockSize3DES  -  1);
的NSLog(@%祖,sizof uint8_t有中:%祖,bufferPtrSize,的sizeof(uint8_t有));
为size_t movedBytes = 0;
uint8_t有* bufferPtr =的malloc(bufferPtrSize *的sizeof(uint8_t有));
的NSLog(@%祖的sizeof(bufferPtr));
memset的((无效*)bufferPtr,为0x0,bufferPtrSize);
的NSLog(@%祖的sizeof(bufferPtr));

常量无效* v键= [[NSData的base64DataFromString:键]字节]
常量无效* vinitVec = [[NSData的base64DataFromString:initVec]字节]
的NSLog(@vinitvec:%@,[[NSData的base64DataFromString:initVec]说明]);

CCCryptorStatus ccStatus;
ccStatus = CCCrypt(encryptorDecrypt,
                   kCCAlgorithm3DES,
                   kCCOptionPKCS7Padding和放大器; kCCModeCBC,
                   v键,
                   kCCKeySize3DES,
                   vinitVec,
                   vplainText,
                   plainTextBufferSize,
                   (无效*)bufferPtr,
                   bufferPtrSize,
                   &安培; movedBytes);

NSData的*结果= [NSData的dataWithBytes:(常量无效*)bufferPtr长度:(NSUInteger)movedBytes]。
的NSString *海峡= [NSString的base64StringFromData:结果长度:result.length]。
的NSLog(@%@,STR);
返回海峡;
 

}

这code成功地加密和解密的字符串。但是,它不会从.NET和Java的结果相符。 谢谢

解决方案

已经找到了加密值的上述问题的解决方案产生不同的iOS和.NET或Java。

解决方法:
1.在Android和.NET你必须使用大小为16的密钥字节(如:钥匙=1234567890123456)

在iOS的,你需要使用24字节的密钥大小,但密钥的生成,使差别不大。 在Android或.NET(16字节)用于使用相同的密钥,并与前8个字节相同的密钥将其追加。

key16Byte =1234567890123456// Android和.NET关键 key24Byte = key16Byte +12345678// iOS和Java的关键,复制前8个字节的16Byte关键 // new24ByteKey =123456789012345612345678

<醇开始=2> 从CCypher模式

;
  • 删除kCCModeCBC&AMP。

  • 某些值要求我在下面提到的code以下已经改变了CCCrypt功能字节。像KEYDATA,encryptData。

  • 原因产生不同的加密: Android和.NET - 这需要16Byte键和内部复制,并生成一个24Byte键

    Java的 - 它抛出一个异常无效的密钥长度,如果你提供一个16Byte键值

    iOS的 - 它生成的加密值16Byte和24Byte两个值没有抛出任何异常,所以我们得到的情况下16Byte密钥生成一个不同的加密的原因

    的Java code

     公共类EncryptionHelper {
    
    //加密字符串和连接code为Base64
    公共静态字符串encryptText(明文字符串,字符串键,字符串IV)抛出异常{
       // ----使用指定的3DES密钥和IV从其他来源--------------
        byte []的明文= plainText.getBytes(); //输入
        byte []的tdesKeyData = key.getBytes(); //你的加密密钥
    
        byte []的myIV = IV.getBytes(); //初始化向量
    
        密c3des = Cipher.getInstance(DESede / CBC / PKCS5Padding);
        SecretKeySpec的myKey =新SecretKeySpec(tdesKeyData,DESede);
        IvParameterSpec ivspec =新IvParameterSpec(myIV);
    
        c3des.init(Cipher.ENCRYPT_MODE,的myKey,ivspec);
        byte []的密文= c3des.doFinal(明文);
        字符串encryptedString = Base64.en codeToString(密文,
                Base64.DEFAULT);
        //返回的Base64 coder.en codeString的(新的字符串(密文));
        返回encryptedString;
    }
     

    的iOS code:

       - (的NSString *)加密:(的NSString *)encryptValue键:(的NSString *)key24Byte四:(的NSString *)IV {
        //首先我们需要prepare关键
        如果([密钥长度]!= 24)
            返回@需要24个字节的关键,因为在Android和.NET用来调用函数generate24ByteKeySameAsAndroidDotNet有16Byte键相同的; //临时错误信息
    
    
        的NSData * KEYDATA = [key24Byte dataUsingEncoding:NSUTF8StringEncoding]。
    
        //我们的关键是准备好了,让我们prepare其他缓冲区和移动的字​​节长度
        的NSData * encryptData = [encryptValue dataUsingEncoding:NSUTF8StringEncoding]。
        为size_t resultBufferSize = [encryptData长度] + kCCBlockSize3DES;
        unsigned char型ResultBuffer的[resultBufferSize]
        为size_t移动= 0;
    
        // DES-CBC需要显式的初始化向量(IV)的
        // IV  - 对MD5密钥下半年
        NSMutableData * ivData = [[ⅣdataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
        NSMutableData * IV = [NSMutableData dataWithData:ivData]。
    
        CCCryptorStatus cryptorStatus = CCCrypt(kCCEncrypt,kCCAlgorithm3DES,
                                                kCCOptionPKCS7Padding,[KEYDATA字节]
                                                kCCKeySize3DES,[四字节]
                                                [encryptData字节],[encryptData长度]
                                                ResultBuffer的,resultBufferSize,和放大器;移动);
    
        如果(cryptorStatus == kCCSuccess){
            返回[[NSData的dataWithBytes:ResultBuffer的长度:移动] base64En codedStringWithOptions:0];
        } 其他 {
            回零;
        }
    }
     

    的iOS

       - (的NSString *)generate24ByteKeySameAsAndroidDotNet:(的NSString *)键{
        的NSString * new24ByteKey =键;
    
        ;
        new24ByteKey = [new24ByteKey stringByAppendingString:[键substringWithRange:NSMakeRange(0,8)];
    
        返回new24ByteKey;
    }
     

    I'm trying do some encrypt something using 3des on the iOS that must match the results from java and .NET.

    Java code is :

    public class EncryptionHelper {
    
    // Encrypts string and encode in Base64
    public static String encryptText(String plainText,String key, String IV) throws Exception {
        // ---- Use specified 3DES key and IV from other source --------------
        byte[] plaintext = plainText.getBytes();//input
        byte[] tdesKeyData = key.getBytes();// your encryption key
    
        byte[] myIV = IV.getBytes();// initialization vector
    
        Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(myIV);
    
        c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
        byte[] cipherText = c3des.doFinal(plaintext);
        String encryptedString = Base64.encodeToString(cipherText,
                Base64.DEFAULT);
        // return Base64Coder.encodeString(new String(cipherText));
        return encryptedString;
    }
    

    }

    and iOS code for the same is :

    -(NSString*)new3DESwithoperand:(NSString*)plaintext encryptOrDecrypt:(CCOperation)encryptorDecrypt key:(NSString*)key initVec:(NSString*)initVec
    {
    
    NSData* data = [plaintext dataUsingEncoding:NSUTF8StringEncoding];
    const void *vplainText = [data bytes];;
    size_t plainTextBufferSize = [data length];
    NSLog(@"%@, Length: %u",[data description],[data length]);
    
    size_t bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
    NSLog(@"%zu, sizof of uint8_t: %zu",bufferPtrSize, sizeof(uint8_t));
    size_t movedBytes = 0;
    uint8_t *bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
    NSLog(@"%zu",sizeof(bufferPtr));
    memset((void*)bufferPtr, 0x0, bufferPtrSize);
    NSLog(@"%zu",sizeof(bufferPtr));
    
    const void * vkey = [[NSData base64DataFromString:key] bytes];
    const void *vinitVec = [[NSData base64DataFromString:initVec] bytes];
    NSLog(@"vinitvec: %@",[[NSData base64DataFromString:initVec] description]);
    
    CCCryptorStatus ccStatus;
    ccStatus = CCCrypt(encryptorDecrypt,
                       kCCAlgorithm3DES,
                       kCCOptionPKCS7Padding & kCCModeCBC,
                       vkey,
                       kCCKeySize3DES,
                       vinitVec,
                       vplainText,
                       plainTextBufferSize,
                       (void*)bufferPtr,
                       bufferPtrSize,
                       &movedBytes);
    
    NSData* result = [NSData dataWithBytes:(const void*)bufferPtr length:(NSUInteger)movedBytes];
    NSString* str = [NSString base64StringFromData:result length:result.length];
    NSLog(@"%@",str);
    return str;
    

    }

    This code successfully encrypts and decrypts a string. However, it does not match the results from .NET and java. Thank you

    解决方案

    Have found a solution for the above problem of encryption value generated different on iOS and .NET or Java.

    Solution:
    1. In Android and .NET you have to use a key of size 16 Bytes (eg: key="1234567890123456")

    In iOS you need to use a key size of 24 bytes but the generation of key makes a little difference. Use the same key as used in Android or .NET (16 bytes) and append it with the first 8 Bytes of the same key.

    key16Byte = "1234567890123456" //Android and .NET key key24Byte = key16Byte + "12345678" //ios and Java key, Replicated first 8 Bytes of 16Byte key //new24ByteKey = "123456789012345612345678"

    1. Remove "& kCCModeCBC" from CCypher Mode.

    2. Some values require bytes in CCCrypt function which I have changed in the below mentioned code below. like keyData, encryptData.

    Reason for different encryption generated: Android and .NET - It takes 16Byte key and internally replicates, and generates a 24Byte key.

    Java - It throws an Exception "Invalid key length", if you provide a 16Byte key value.

    iOS - It generates encryption value with 16Byte and 24Byte both values without throwing any exception, so is the reason we get a different encryption generated in case of 16Byte key.

    Java Code

    public class EncryptionHelper {
    
    // Encrypts string and encode in Base64
    public static String encryptText(String plainText,String key, String IV) throws Exception {
       // ---- Use specified 3DES key and IV from other source --------------
        byte[] plaintext = plainText.getBytes();//input
        byte[] tdesKeyData = key.getBytes();// your encryption key
    
        byte[] myIV = IV.getBytes();// initialization vector
    
        Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(myIV);
    
        c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
        byte[] cipherText = c3des.doFinal(plaintext);
        String encryptedString = Base64.encodeToString(cipherText,
                Base64.DEFAULT);
        // return Base64Coder.encodeString(new String(cipherText));
        return encryptedString;
    }
    

    iOS Code:

    - (NSString *)encrypt:(NSString *)encryptValue key:(NSString *)key24Byte IV:(NSString *)IV{
        // first of all we need to prepare key
        if([key length] != 24)
            return @"Require 24 byte key, call function generate24ByteKeySameAsAndroidDotNet with a 16Byte key same as used in Android and .NET"; //temporary error message
    
    
        NSData *keyData = [key24Byte dataUsingEncoding:NSUTF8StringEncoding];
    
        // our key is ready, let's prepare other buffers and moved bytes length
        NSData *encryptData = [encryptValue dataUsingEncoding:NSUTF8StringEncoding];
        size_t resultBufferSize = [encryptData length] + kCCBlockSize3DES;
        unsigned char resultBuffer[resultBufferSize];
        size_t moved = 0;
    
        // DES-CBC requires an explicit Initialization Vector (IV)
        // IV - second half of md5 key
        NSMutableData *ivData = [[IV dataUsingEncoding:NSUTF8StringEncoding]mutableCopy];
        NSMutableData *iv = [NSMutableData dataWithData:ivData];
    
        CCCryptorStatus cryptorStatus = CCCrypt(kCCEncrypt, kCCAlgorithm3DES,
                                                kCCOptionPKCS7Padding , [keyData bytes],
                                                kCCKeySize3DES, [iv bytes],
                                                [encryptData bytes], [encryptData length],
                                                resultBuffer, resultBufferSize, &moved);
    
        if (cryptorStatus == kCCSuccess) {
            return [[NSData dataWithBytes:resultBuffer length:moved] base64EncodedStringWithOptions:0];
        } else {
            return nil;
        }
    }
    

    iOS

    -(NSString *)generate24ByteKeySameAsAndroidDotNet:(NSString *)key{
        NSString *new24ByteKey = key;
    
        ;
        new24ByteKey = [new24ByteKey stringByAppendingString:[key substringWithRange:NSMakeRange(0, 8)]];
    
        return new24ByteKey;
    }
    

    这篇关于加密为iOS 3DES不一样的Andr​​oid和.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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