Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓->;iOS密码迁移_Android_Iphone_Objective C_Ios_Encryption - Fatal编程技术网

Android 安卓->;iOS密码迁移

Android 安卓->;iOS密码迁移,android,iphone,objective-c,ios,encryption,Android,Iphone,Objective C,Ios,Encryption,我必须将Android应用程序迁移到使用密码的iOS。下面是Android代码: PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); ... byte[] result = Hex.encode(output, 0, output.length); String resultS = new String(Str.toChars(resul

我必须将Android应用程序迁移到使用密码的iOS。下面是Android代码:

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
...
byte[] result = Hex.encode(output, 0, output.length);
String resultS = new String(Str.toChars(result));
我尝试了很多objective-c的东西,但是找不到一种方法来获得与Java相同的字符串。我在这里使用了iOS代码(还有很多,但都是一样的)

然后,要在iOS上获取字符串,请使用以下命令:

NSString* resultS = [encryptedData base64Encoding]
但是结果字符串不匹配。可能问题在于如何处理NSData的编码(Java版本似乎不使用base64,我可以吗?)

有什么想法吗

编辑1:

好的,我取得了一些进步(我希望如此)。检查java代码时,他们使用块大小为8的DES/CBC,键为24个字符。因此,我将代码从CocoaFu更改为:

- (NSData *)doCipher:(NSData *)dataIn
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
uint8_t iv[kChosenCipherBlockSize];
memset((void *) iv, 0x0, (size_t) sizeof(iv));

ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmDES,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes, 
                   kCCKeySize3DES,
                   (const void *)iv,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

if (ccStatus != kCCSuccess) {
    NSLog(@"CCCrypt status: %d", ccStatus);
}

dataOut.length = cryptBytes;

return dataOut;
}
- (NSData *)doCipher:(NSData *)dataIn
             key:(NSData *)symmetricKey
         context:(CCOperation)encryptOrDecrypt
{
CCCryptorStatus ccStatus   = kCCSuccess;
size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
uint8_t iv[kChosenCipherBlockSize];
memset((void *) iv, 0x0, (size_t) sizeof(iv));

ccStatus = CCCrypt( encryptOrDecrypt,
                   kCCAlgorithmDES,
                   kCCOptionPKCS7Padding,
                   symmetricKey.bytes, 
                   kCCKeySize3DES,
                   (const void *)iv,
                   dataIn.bytes,
                   dataIn.length,
                   dataOut.mutableBytes,
                   dataOut.length,
                   &cryptBytes);

if (ccStatus != kCCSuccess) {
    NSLog(@"CCCrypt status: %d", ccStatus);
}

dataOut.length = cryptBytes;

return dataOut;
}

当我尝试用java编码“test”消息时,我得到了“f69d7c299597c880”,但在iOS上(当然使用相同的键),我得到了3DES的“<91864397><41434eaa>”,DES的“<4bad6f7f>”。还有什么可以更改的吗?

您试图在密码上使用CBC模式,但iOS不支持CBC模式,只支持ECB模式

这是一个困难的问题,因为它要么有效,要么没有什么线索。最好的方法是尽可能简单地开始,并逐步积累

第一件事是确切地了解java代码在做什么。对于CBC模式,将有一个iv(初始化值),但在发布的java代码中没有明确指定。您需要了解java代码正在使用什么。同时发布完整的java代码

从代码
PaddedBufferedBlockCipher
中,我推断存在块填充,这可能是PKCS5或PKCS7,从填充角度来看,两者都是相同的,iOS等效物是KCCOPIONPKCS7Padding。确保这一点

确保密钥长度相同,对于AES,选项为128、192和256位,除非有特定原因使用128

代码
Hex.encode
似乎暗示输出是十六进制编码的,您需要在iOS上执行相同的操作,这与Base64不同

另一个主要问题是让双方的所有参数都相同。特别令人感兴趣的是:

  • 加密密钥值和大小
  • 模式:CBC、ECB等(您可能应该使用CBC)
  • 大多数模式都需要初始化向量(iv)
  • 填充方法:PKCS7等(AES是块密码,需要输入块大小的倍数)
  • 任何加密后处理,十六进制或Base64编码
  • 尽可能简单地开始,所有0的iv,一个块大小的数据,没有填充,简单的键,没有后处理。从可以在系统之间共享的文件中获取密钥、iv和测试数据,这将防止一些错误,例如c字符串jul终止等

    以下是我使用的iOS代码:

    #import <CommonCrypto/CommonCryptor.h>
    
    + (NSData *)doCipher:(NSData *)dataIn
                      iv:(NSData *)iv
                     key:(NSData *)symmetricKey
                 context:(CCOperation)encryptOrDecrypt
    {
        CCCryptorStatus ccStatus   = kCCSuccess;
        size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
        NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeAES128];
    
        ccStatus = CCCrypt( encryptOrDecrypt,
                           kCCAlgorithmAES128,
                           kCCOptionPKCS7Padding,
                           symmetricKey.bytes, 
                           kCCKeySizeAES128,
                           iv.bytes,
                           dataIn.bytes,
                           dataIn.length,
                           dataOut.mutableBytes,
                           dataOut.length,
                           &cryptBytes);
    
        if (ccStatus != kCCSuccess) {
            NSLog(@"CCCrypt status: %d", ccStatus);
        }
    
        dataOut.length = cryptBytes;
    
        return dataOut;
    }
    
    #导入
    +(NSData*)doCipher:(NSData*)数据输入
    四:(NSData*)四
    键:(NSData*)symmetricKey
    上下文:(cOperation)encryptOrDecrypt
    {
    CCCryptorStatus ccStatus=KCCSucces;
    size\u t cryptBytes=0;//移动到缓冲区的字节数。
    NSMutableData*dataOut=[NSMutableData dataWithLength:dataIn.length+kCCBlockSizeAES128];
    ccStatus=CCCrypt(encryptOrDecrypt,
    KCcalGorithmae128,
    KCCOPIONPKCS7填充,
    symmetricKey.bytes,
    kCCKeySizeAES128,
    iv.字节,
    以字节为单位的数据,
    dataIn.length,
    dataOut.mutableBytes,
    dataOut.length,
    &密码字节);
    if(ccStatus!=KCCSucces){
    NSLog(@“CCCrypt状态:%d”,ccStatus);
    }
    dataOut.length=cryptBytes;
    返回数据输出;
    }
    
    还要将Security.framework添加到项目中

    如果安全性很重要,请考虑有安全经验的人创建代码和协议。如果安全性不重要,只需在clear中发送密码即可

    一个应用程序中的一些bug并没有那么糟糕,应用程序基本上仍然可以工作,一个安全性bug和所有安全性都丢失了

    良好的安全性并不像人们想象的那么容易——或者像我妻子说的那样:“如果加密很容易,每个人都会这么做”,但她的意思是正确的。

    好吧,我取得了一些进展(我希望如此)。检查java代码时,他们使用块大小为8的DES/CBC,键为24个字符。因此,我将代码从CocoaFu更改为:

    - (NSData *)doCipher:(NSData *)dataIn
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt
    {
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
    uint8_t iv[kChosenCipherBlockSize];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));
    
    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmDES,
                       kCCOptionPKCS7Padding,
                       symmetricKey.bytes, 
                       kCCKeySize3DES,
                       (const void *)iv,
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &cryptBytes);
    
    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }
    
    dataOut.length = cryptBytes;
    
    return dataOut;
    }
    
    - (NSData *)doCipher:(NSData *)dataIn
                 key:(NSData *)symmetricKey
             context:(CCOperation)encryptOrDecrypt
    {
    CCCryptorStatus ccStatus   = kCCSuccess;
    size_t          cryptBytes = 0;    // Number of bytes moved to buffer.
    NSMutableData  *dataOut    = [NSMutableData dataWithLength:dataIn.length + kCCBlockSizeDES];
    uint8_t iv[kChosenCipherBlockSize];
    memset((void *) iv, 0x0, (size_t) sizeof(iv));
    
    ccStatus = CCCrypt( encryptOrDecrypt,
                       kCCAlgorithmDES,
                       kCCOptionPKCS7Padding,
                       symmetricKey.bytes, 
                       kCCKeySize3DES,
                       (const void *)iv,
                       dataIn.bytes,
                       dataIn.length,
                       dataOut.mutableBytes,
                       dataOut.length,
                       &cryptBytes);
    
    if (ccStatus != kCCSuccess) {
        NSLog(@"CCCrypt status: %d", ccStatus);
    }
    
    dataOut.length = cryptBytes;
    
    return dataOut;
    }
    

    当我尝试用java编码“test”消息时,我得到了“f69d7c299597c880”,但在iOS上(当然使用相同的键),我得到了3DES的“<91864397><41434eaa>”,DES的“<4bad6f7f>”。还有什么可以更改的吗?

    iOS CommonCrypto支持CBC,默认值为CBC。在SO引用中添加了注释,以更正CBC受支持的错误。我认为正如CocoaFu所说,CBC是Apple头文件CommonCryptor.h:初始化向量中的默认值,可选。启用密码块链接(CBC)模式时,由块密码使用。如果存在,则长度必须与选定算法的块大小相同。如果选择了CBC模式(由于选项标志中没有KCCOPIONECBMODE位),并且不存在IV,则将使用NULL(全零)IV。@CocoaFu ok,我将知道Base64编码与十六进制编码不同。在比较output.TKS之前使用相同的编码!我在原来的帖子上取得了一些进步,希望你能帮助我。