DES加解密 (iOS,Java保持一致互相可以加解密)

来源:互联网 发布:淘宝客服回复语大全 编辑:程序博客网 时间:2024/05/14 05:06

这几天再做一个项目,服务器和移动端要进行数据传输,但有选择了DES加解密;可是起初一直不能很好的互相加解。

下面上代码,说几个需要注意保持一致的地方。

需要注意的几个参数,首先key要各个端保持一致;

然后iv也要保持一致,不然加密解密会不一样。

其中java会遇到一个报错 Wrong IV length: must be 8 bytes long:这个是key的长度造成的,但官方说密钥是56位长度,这个有点不太明白,但你只要记住key的长度必须是8位。

IV向量:主要作用就是防止篡改的,这个地方如果不一致会导致数据的头部解出来是乱码,而后面正常。(所以有时java刚一解析前几个字符就已经报错了)。


ios:

+ (NSString *)encrypt:(NSString *)sText encryptOrDecrypt:(CCOperation)encryptOperation key:(NSString *)key
{
    const Byte iv[] = {1,2,3,4,5,6,7,8};
    NSString *tempText = nil;
    NSData *textData = [sText dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [textData length];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding,
                                          [key UTF8String], kCCKeySizeDES,
                                          iv,
                                          [textData bytes], dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        //             ciphertext = [GTMBase64 encodehaha:data];
        //             ciphertext = [self parseByte2HexString:data];
        tempText = [self parseByte2HexString:buffer];
        tempText = [tempText uppercaseString];
        NSLog(@"加密结果%@------%@",tempText, data);
        
    }
    return tempText;
}

+(NSString *) parseByte2HexString:(Byte *) bytes
{
    NSMutableString *hexStr = [[NSMutableString alloc]init];
    int i = 0;
    if(bytes)
    {
        while (bytes[i] != '\0')
        {
            NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
            if([hexByte length]==1)
                [hexStr appendFormat:@"0%@", hexByte];
            else
                [hexStr appendFormat:@"%@", hexByte];
            
            i++;
        }
    }
    NSLog(@"bytes 的16进制数为:%@",hexStr);
    return hexStr;
}



//解密
+ (NSString *) decryptUseDES:(NSString*)cipherText key:(NSString*)key
{
    NSData* temData = [GTMBase64 decodeString:cipherText];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesDecrypted = 0;
    Byte iv[] = {1,2,3,4,5,6,7,8};
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding,
                                          [key UTF8String],
                                          kCCKeySizeDES,
                                          iv,
                                          [temData bytes],
                                          [temData length],
                                          buffer,
                                          1024,
                                          &numBytesDecrypted);
    NSString* tempText = nil;
    if (cryptStatus == kCCSuccess) {
        NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
        tempText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }
    NSLog(@"解密的%@",tempText);
    return tempText;
}




Java:

    public static String encryptDES(String encryptString, String encryptKey) throws Exception {
        SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
        return byte2hex(encryptedData);
    }

    public static void main(String[] args) throws Exception {
        String source = "测试数据";
        String aim = StringCrypUtil.encryptDES(source, "infoware");
        System.out.println(aim);
    }

    private static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }


到此终于调通了。



因为我们项目不需要base64加密,所以只需要把获取到的buffer做16进制以及大写处理,此时出现一个问题:采用PKCS7Padding或者PKCS5Padding这种加密方式,末端添加的数据可能不固定,在解码后需要把末端多余的字符去掉,比较棘手,现在发现有的设备加密是和java端一致的,有的设备会在末端加几位(至于是几这个随机)。  现在临时做法是只保留64位字符,然后传给服务端。为什么不base64编码呢,好蛋疼。继续找解决方法。



原创粉丝点击