【问题标题】:PBEWithMD5AndDES Encryption in iOSiOS 中的 PBEWithMD5AndDES 加密
【发布时间】:2018-07-02 10:20:22
【问题描述】:

我在 iOS 中遇到了 PBEWithMD5AndDES 加密问题。我已经使用https://gist.github.com/788840/24bc73ecd0ac3134cbd242892c74a06ac561d37b 对我的字符串进行了加密和解密。

问题是我得到不同的加密值,具体取决于我的方法所在的类。例如,我将所有加密方法移动到一个帮助程序类中并运行它。我注意到我得到了不同的加密值。

我现在在不同的类中有相同方法的两个相同版本,并且我正在并排运行它们。他们得到不同的加密值,一个不能解密其他的。我对此感到有些困惑。

这是进行加密/解密的辅助类。

@implementation CryptoHelper

#pragma mark -
#pragma mark Init Methods
- (id)init
{
    if(self = [super init])
    {

    }
    return self;
}

#pragma mark -
#pragma mark String Specific Methods

/** 
 *  Encrypts a string for social blast service. 
 *  
 *  @param  plainString The string to encrypt;
 *
 *  @return NSString    The encrypted string. 
 */
- (NSString *)encryptString: (NSString *) plainString{

    // Convert string to data and encrypt
    NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];



    // Get encrypted string from data
    return [data base64EncodingWithLineLength:1024];

}


/** 
 *  Descrypts a string from social blast service. 
 *  
 *  @param  plainString The string to decrypt;
 *
 *  @return NSString    The decrypted string. 
 */
- (NSString *)decryptString: (NSString *) encryptedString{

    // decrypt the data
    NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];

    // extract and return string
    return [NSString stringWithUTF8String:[data bytes]];

}


#pragma mark -
#pragma mark Crypto Methods

- (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
    return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
}

- (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
    return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
}

- (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
{
    NSLog(@"helper data = %@", inData);

    static const char gSalt[] =
    {
        (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
        (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA
    };

    unsigned char *salt = (unsigned char *)gSalt;
    int saltLen = strlen(gSalt);
    int iterations = 15;

    EVP_CIPHER_CTX cipherCtx;


    unsigned char *mResults; // allocated storage of results
    int mResultsLen = 0;

    const char *cPassword = [password UTF8String];

    unsigned char *mData = (unsigned char *)[inData bytes];
    int mDataLen = [inData length];


    SSLeay_add_all_algorithms();
    /*X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
                                          iterations, salt, saltLen);*/
        const EVP_CIPHER *cipher = EVP_des_cbc();

    // Need to set with iv
    X509_ALGOR *algorithm = PKCS5_pbe2_set_iv(cipher, iterations, 
                                          salt, saltLen, salt, NID_hmacWithMD5);


    memset(&cipherCtx, 0, sizeof(cipherCtx));

    if (algorithm != NULL)
    {
        EVP_CIPHER_CTX_init(&(cipherCtx));



        if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword),
                               algorithm->parameter, &(cipherCtx), direction))
        {

            EVP_CIPHER_CTX_set_padding(&cipherCtx, 1);

            int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx);
            int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt
            mResults = (unsigned char *)OPENSSL_malloc(allocLen);


            unsigned char *in_bytes = mData;
            int inLen = mDataLen;
            unsigned char *out_bytes = mResults;
            int outLen = 0;



            int outLenPart1 = 0;
            if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen))
            {
                out_bytes += outLenPart1;
                int outLenPart2 = 0;
                if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2))
                {
                    outLen += outLenPart1 + outLenPart2;
                    mResults[outLen] = 0;
                    mResultsLen = outLen;
                }
            } else {
                unsigned long err = ERR_get_error();

                ERR_load_crypto_strings();
                ERR_load_ERR_strings();
                char errbuff[256];
                errbuff[0] = 0;
                ERR_error_string_n(err, errbuff, sizeof(errbuff));
                NSLog(@"OpenSLL ERROR:\n\tlib:%s\n\tfunction:%s\n\treason:%s\n",
                      ERR_lib_error_string(err),
                      ERR_func_error_string(err),
                      ERR_reason_error_string(err));
                ERR_free_strings();
            }


            NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; //(NSData *)encr_buf;


            //NSLog(@"encryption result: %@\n", [encryptedData base64EncodingWithLineLength:1024]);

            EVP_cleanup();

            return encryptedData;
        }
    }
    EVP_cleanup();
    return nil;

}

@end

我正在尝试复制此 java 函数的结果。我有同样的盐。

public DesEncrypter(String passPhrase) {
    try {
        // Create the key
        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance(
            "PBEWithMD5AndDES").generateSecret(keySpec);
        ecipher = Cipher.getInstance(key.getAlgorithm());
        dcipher = Cipher.getInstance(key.getAlgorithm());

        // Prepare the parameter to the ciphers
        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);

        // Create the ciphers
        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    } catch (java.security.InvalidAlgorithmParameterException e) {
    } catch (java.security.spec.InvalidKeySpecException e) {
    } catch (javax.crypto.NoSuchPaddingException e) {
    } catch (java.security.NoSuchAlgorithmException e) {
    } catch (java.security.InvalidKeyException e) {
    }
}

【问题讨论】:

    标签: iphone objective-c ios encryption openssl


    【解决方案1】:

    接受的答案似乎使用了 iOS SDK 中未包含的 OpenSSL。这是一个使用包含的 CommonCrypto 库(在 libSystem 中)的加密和解密解决方案。我有点像 ObjC n00b,所以对这段代码持保留态度。顺便说一句,这段代码将成功解密使用 java 的 PBEWithMD5AndDES 密码加密的数据。希望这可以为其他人节省一两天的时间。

    #include <CommonCrypto/CommonDigest.h>
    #include <CommonCrypto/CommonCryptor.h>
    
    
    +(NSData*) cryptPBEWithMD5AndDES:(CCOperation)op usingData:(NSData*)data withPassword:(NSString*)password andSalt:(NSData*)salt andIterating:(int)numIterations {
        unsigned char md5[CC_MD5_DIGEST_LENGTH];
        memset(md5, 0, CC_MD5_DIGEST_LENGTH);
        NSData* passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
    
        CC_MD5_CTX ctx;
        CC_MD5_Init(&ctx);
        CC_MD5_Update(&ctx, [passwordData bytes], [passwordData length]);
        CC_MD5_Update(&ctx, [salt bytes], [salt length]);
        CC_MD5_Final(md5, &ctx);
    
        for (int i=1; i<numIterations; i++) {
            CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
        }
    
        size_t cryptoResultDataBufferSize = [data length] + kCCBlockSizeDES;
        unsigned char cryptoResultDataBuffer[cryptoResultDataBufferSize];
        size_t dataMoved = 0;
    
        unsigned char iv[kCCBlockSizeDES];
        memcpy(iv, md5 + (CC_MD5_DIGEST_LENGTH/2), sizeof(iv)); //iv is the second half of the MD5 from building the key
    
        CCCryptorStatus status =
            CCCrypt(op, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, (CC_MD5_DIGEST_LENGTH/2), iv, [data bytes], [data length],
                cryptoResultDataBuffer, cryptoResultDataBufferSize, &dataMoved);
    
        if(0 == status) {
            return [NSData dataWithBytes:cryptoResultDataBuffer length:dataMoved];
        } else {
            return NULL;
        }
    }
    

    【讨论】:

    • 这很好用。对于尝试使用 Java 的 PBEWithMD5AndDES 的其他人,如果在加密过程中没有提供盐,算法会在消息前加上盐(8 字节长),因此您的解密将类似于:NSData *inputData = [NSData dataFromBase64String:message]; NSData *salt = [inputData subdataWithRange:NSMakeRange(0, 8)]; inputData = [inputData subdataWithRange:NSMakeRange(8, inputData.length-8)]; NSData *outputData = [self cryptPBEWithMD5AndDES:kCCDecrypt usingData:inputData withPassword:key andSalt:salt andIterating:1000];
    • 有没有人成功使用这段代码用 Obj-C 加密然后用 Java 解密?
    • 这段代码对我没有帮助。对于从 0 到 1000 的所有迭代,它总是不返回任何结果
    • 你能帮我提供 swift 版本吗?
    • 嗨 - 我正在尝试在 Swift 中使用此方法,我能够编译并构建它,但不确定 CCOperation 是什么。我应该通过什么。有人可以举一个例子,说明我如何从 Swift 调用这个方法,用 sn-p 初始化所有那里的参数,来自标准 Swift 字符串
    【解决方案2】:

    问题是你没有为你的加密指定一个IV,这样会自动为你生成一个随机数,这也是你每次得到不同结果的原因。

    尝试使用 PKCS5_pbe2_set_iv 而不是 PKCS5_pbe2_set 提供明确的 IV 值,您可以随机选择,就像您的盐值一样。

    【讨论】:

    • 这很有意义。 aiv 和 prf_nid 应该是什么样子?只是一个字符串和一个整数?
    • prf_nid 是伪随机函数的 nid,你可以以 NID_hmacWithSHA1 为例。 aiv 是一个随机的无符号字符*。它的长度可以使用EVP_CIPHER_iv_length来确定。
    • 我正在尝试通过使用它来获取长度,int cipherLen = EVP_CIPHER_iv_length(NID_pbeWithMD5AndDES_CBC); 但是当我运行它时出现错误的访问错误。我传错了吗?
    • 我也收到了这个X509_ALGOR *algorithm = PKCS5_pbe2_set(NID_pbeWithMD5AndDES_CBC, iterations, salt, saltLen);的错误@PKCS5_pbe_set和PKCS5_pbe2_set有什么区别?
    • EVP_CIPHER_iv_lengthPKCS5_pbe2_set 都需要 EVP_CIPHER * 而不是 NID。您可以使用 EVP_get_cipherbynid 从 nid 获取 EVP_CIPHER *。
    【解决方案3】:

    使用 johwayner 的响应,我稍微修复了这个问题,以便从 jasypt 中解密 Java 的 PBEWithMD5AndDES。这是我最终得到的结果:

    @interface NSData (PBEEncryption)
    
    /**
     * Decrypt the receiver using PKCS#5 PBE with MD5 and DES assuming that the salt is prefixed into the first 8 bytes of
     * the data and the number of key obtention iterations is 1000. This is compatible with Java's PBEWithMD5AndDES
     * encryption when the encryption generates a random salt for the data (the default when providing no salt).
     */
    - (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password;
    
    /**
     * Decrypt the receiver using PKCS#5 PBE with MD5 and DES. Explicitly provide the salt and number of key obtention
     * iterations.
     */
    - (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations;
    
    @end
    
    
    @implementation NSData (PBEEncryption)
    
    - (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password {
        NSData *salt = nil;
        NSData *input = self;
        if ([input length] > 8) {
            salt = [input subdataWithRange:NSMakeRange(0, 8)];
            input = [input subdataWithRange:NSMakeRange(8, [input length] - 8)];
        }
        return [input decrytpPBEWithMD5AndDESUsingPassword:password salt:salt iterations:1000];
    }
    
    - (NSData *)decrytpPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations {
        unsigned char md5[CC_MD5_DIGEST_LENGTH] = {};
    
        CC_MD5_CTX ctx;
        CC_MD5_Init(&ctx);
        CC_MD5_Update(&ctx, [password bytes], [password length]);
        CC_MD5_Update(&ctx, [salt bytes], [salt length]);
        CC_MD5_Final(md5, &ctx);
    
        for (NSUInteger i = 1; i < iterations; i++) {
            CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
        }
    
        // initialization vector is the second half of the MD5 from building the key
        unsigned char iv[kCCBlockSizeDES];
        assert(kCCBlockSizeDES == CC_MD5_DIGEST_LENGTH / 2);
        memcpy(iv, md5 + kCCBlockSizeDES, sizeof(iv));
    
        NSMutableData *output = [NSMutableData dataWithLength:([self length] + kCCBlockSize3DES)];
        size_t outputLength = 0;
        CCCryptorStatus status =
            CCCrypt(kCCDecrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, kCCBlockSizeDES, iv,
                    [self bytes], [self length], [output mutableBytes], [output length], &outputLength);
    
        if (status == kCCSuccess) { [output setLength:outputLength]; }
        else { output = nil; }
    
        return output;
    }
    
    @end
    

    这样使用:

    NSString *password = @"myTopSecretPassword";
    NSData *inputData = [NSData dataFromBase64String:@"base64string"];
    NSData *outputData = [inputData decrytpPBEWithMD5AndDESUsingPassword:
                          [password dataUsingEncoding:NSUTF8StringEncoding]];
    

    【讨论】:

    • [NSData dataFromBase64String:] 方法的来源是什么?
    • @trololo 那里有很多。搜索 Google 并选择一个。
    • 谢谢。但我想说代码对我不起作用。我已经尝试了从 0 到 1000 的所有迭代,但总是没有结果。我加密字符串时的输入迭代次数为 20。密码和盐是相同的。
    • @trololo 您可能想在 Stack Overflow 上提出一个新问题并发布您的所有代码以及您尝试过的内容。也许有人可以提供帮助。
    【解决方案4】:

    不确定这里接受答案/投票的协议是什么。如果我做错了,我很抱歉。答案原来是盐中缺少最后一个字节。我实际上不需要使用 3DES 加密的 IV。我赞成另一个答案,因为它有助于更​​多地了解加密。

    这是最终的目标 c 类。

    @implementation CryptoHelper
    
    #pragma mark -
    #pragma mark Init Methods
    - (id)init
    {
        if(self = [super init])
        {
    
        }
        return self;
    }
    
    #pragma mark -
    #pragma mark String Specific Methods
    
    /** 
     *  Encrypts a string for social blast service. 
     *  
     *  @param  plainString The string to encrypt;
     *
     *  @return NSString    The encrypted string. 
     */
    - (NSString *)encryptString: (NSString *) plainString{
    
        // Convert string to data and encrypt
        NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];
    
    
    
        // Get encrypted string from data
        return [data base64EncodingWithLineLength:1024];
    
    }
    
    
    /** 
     *  Descrypts a string from social blast service. 
     *  
     *  @param  plainString The string to decrypt;
     *
     *  @return NSString    The decrypted string. 
     */
    - (NSString *)decryptString: (NSString *) encryptedString{
    
        // decrypt the data
        NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];
    
        // extract and return string
        return [NSString stringWithUTF8String:[data bytes]];
    
    }
    
    
    #pragma mark -
    #pragma mark Crypto Methods
    
    - (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
        return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
    }
    
    - (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
        return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
    }
    
    - (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
    {
        NSLog(@"helper data = %@", inData);
    
        static const char gSalt[] =
        {
            (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
            (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
            (unsigned char)0x00
        };
    
        unsigned char *salt = (unsigned char *)gSalt;
        int saltLen = strlen(gSalt);
        int iterations = 15;
    
        EVP_CIPHER_CTX cipherCtx;
    
    
        unsigned char *mResults; // allocated storage of results
        int mResultsLen = 0;
    
        const char *cPassword = [password UTF8String];
    
        unsigned char *mData = (unsigned char *)[inData bytes];
        int mDataLen = [inData length];
    
    
        SSLeay_add_all_algorithms();
        X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC,
                                              iterations, salt, saltLen);
    
    
    
        memset(&cipherCtx, 0, sizeof(cipherCtx));
    
        if (algorithm != NULL)
        {
            EVP_CIPHER_CTX_init(&(cipherCtx));
    
    
    
            if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword),
                                   algorithm->parameter, &(cipherCtx), direction))
            {
    
                EVP_CIPHER_CTX_set_padding(&cipherCtx, 1);
    
                int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx);
                int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt
                mResults = (unsigned char *)OPENSSL_malloc(allocLen);
    
    
                unsigned char *in_bytes = mData;
                int inLen = mDataLen;
                unsigned char *out_bytes = mResults;
                int outLen = 0;
    
    
    
                int outLenPart1 = 0;
                if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen))
                {
                    out_bytes += outLenPart1;
                    int outLenPart2 = 0;
                    if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2))
                    {
                        outLen += outLenPart1 + outLenPart2;
                        mResults[outLen] = 0;
                        mResultsLen = outLen;
                    }
                } else {
                    unsigned long err = ERR_get_error();
    
                    ERR_load_crypto_strings();
                    ERR_load_ERR_strings();
                    char errbuff[256];
                    errbuff[0] = 0;
                    ERR_error_string_n(err, errbuff, sizeof(errbuff));
                    NSLog(@"OpenSLL ERROR:\n\tlib:%s\n\tfunction:%s\n\treason:%s\n",
                          ERR_lib_error_string(err),
                          ERR_func_error_string(err),
                          ERR_reason_error_string(err));
                    ERR_free_strings();
                }
    
    
                NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; //(NSData *)encr_buf;
    
    
                //NSLog(@"encryption result: %@\n", [encryptedData base64EncodingWithLineLength:1024]);
    
                EVP_cleanup();
    
                return encryptedData;
            }
        }
        EVP_cleanup();
        return nil;
    
    }
    
    @end
    

    【讨论】:

    • 是的,没错。 strlen 正在离开 gSalt 数组的末端。此外,如果您刚刚将 gSalt 声明为 unsigned char 数组而不是 char 数组,则无需将每个元素都转换为 unsigned char
    • 这段代码给 Java 带来了不同的结果。 ios 中的所有加密字符串在所有迭代器值 fcom 0 到 1000 的末尾都有符号等式(“=”)。但在 java 中,字符串没有它们。有人解决这个问题吗?
    【解决方案5】:

    我要感谢 wbyoung。他的回答帮助我解开了如何从 iOS 加密数据并从 Java 解密数据的谜团。以下是我对他的代码所做的补充。

    诀窍是获取用于加密数据的盐,并将其添加到结果中。 Java 将能够解密它。

    @implementation NSData (PBEEncryption)
    
    - (NSData *)encryptPBEWithMD5AndDESUsingPassword:(NSData *)password {
        unsigned char gSalt[] =
        {
            (unsigned char)0x18, (unsigned char)0x79, (unsigned char)0x6D, (unsigned char)0x6D,
            (unsigned char)0x35, (unsigned char)0x3A, (unsigned char)0x6A, (unsigned char)0x60,
            (unsigned char)0x00
        };
    
        NSData *salt = nil;
        salt = [NSData dataWithBytes:gSalt length:strlen(gSalt)];
    
        NSData* encrypted = [self encryptPBEWithMD5AndDESUsingPassword:password salt:salt iterations:1000];
        NSMutableData* result = [NSMutableData dataWithData:salt];
        [result appendData:encrypted];
        return [NSData dataWithData:result];
    
    }
    
    - (NSData *)encryptPBEWithMD5AndDESUsingPassword:(NSData *)password salt:(NSData *)salt iterations:(NSUInteger)iterations {
        unsigned char md5[CC_MD5_DIGEST_LENGTH] = {};
    
        CC_MD5_CTX ctx;
        CC_MD5_Init(&ctx);
        CC_MD5_Update(&ctx, [password bytes], [password length]);
        CC_MD5_Update(&ctx, [salt bytes], [salt length]);
        CC_MD5_Final(md5, &ctx);
    
        for (NSUInteger i = 1; i < iterations; i++) {
            CC_MD5(md5, CC_MD5_DIGEST_LENGTH, md5);
        }
    
        // initialization vector is the second half of the MD5 from building the key
        unsigned char iv[kCCBlockSizeDES];
        assert(kCCBlockSizeDES == CC_MD5_DIGEST_LENGTH / 2);
        memcpy(iv, md5 + kCCBlockSizeDES, sizeof(iv));
    
        NSMutableData *output = [NSMutableData dataWithLength:([self length] + kCCBlockSize3DES)];
        size_t outputLength = 0;
        CCCryptorStatus status =
        CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, md5, kCCBlockSizeDES, iv,
                [self bytes], [self length], [output mutableBytes], [output length], &outputLength);
    
        if (status == kCCSuccess) { [output setLength:outputLength]; }
        else { output = nil; }
    
        return output;
    }
    
    
    @end
    

    加密字符串的对应 Swift 代码:

    static func encryptForOverTheWire(string: String) -> String {
        let stringData = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
        let passwordData = PASSWORD.dataUsingEncoding(NSUTF8StringEncoding)
        let encryptedData = stringData?.encryptPBEWithMD5AndDESUsingPassword(passwordData)
        let base64 = encryptedData?.base64EncodedDataWithOptions(NSDataBase64EncodingOptions())
    
        guard base64 != nil else { return "" }
    
        let result = String(data: base64!, encoding: NSUTF8StringEncoding)
        return result ?? ""
    }
    

    【讨论】:

    • 你能帮我用 swift 版本吗?
    • @Jan 我所做的是包装这段代码,并使用桥接头将其带入 Swift。我将使用 swift 代码更新帖子。因为这里有 C 代码,所以我认为 Swift 本身不可能直接导入。
    【解决方案6】:

    顺便说一句,我可以让它与 Swift 一起工作。我面临的唯一问题是我从目标 C 模块获取数据对象,但是当我尝试转换为字符串时,它给了我 nil。这是代码。请让我知道我在这里做错了什么

    static func encrypt(inString: String) -> String? {
    
        let passwordStr = "blablalba"
        let iterations:Int32 = 19
        let salt = [0x44,  0x44,  0x22,  0x22,  0x56,  0x35,  0xE3, 0x03] as [UInt8]
        let operation: CCOperation = UInt32(kCCEncrypt)
        let saltData = NSData(bytes: salt, length: salt.count)
    
        let out = CryptoHelper.cryptPBE(withMD5AndDES: operation, using: inString.data(using: .utf8), withPassword: passwordStr, andSalt: saltData as Data, andIterating: iterations) as Data
    
        let outString = String.init(data: out, encoding: .utf8)
    
        return outString
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-08
      相关资源
      最近更新 更多