OC JAVA DES加解密保持统一的方法

1.OC

DES加密

最终结果格式是16进制格式:
我写了一个NSString的扩展(NSString+DES)用于处理DES
首先导入加密库:

#import <CommonCrypto/CommonCrypto.h>

其次代码:

//DES加密
- (NSString *)DESString {
    return [self DESString:kDES_KEY];
}

//DES加密
- (NSString *)DESString:(NSString *)key{
    NSString *ciphertext = nil;
    //const char *textBytes = [plainText UTF8String];字符串直接转字节数组就会和java加密结果不一样, 用NSString 转 NSData 取字节流 和java加密结果一致
    NSData *textData = [self dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [textData length];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    Byte iv[] = {1,2,3,4,5,6,7,8};
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,kCCOptionPKCS7Padding|kCCOptionECBMode,[key UTF8String], kCCKeySizeDES,iv,[textData bytes], dataLength,buffer, 1024,&numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        //        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        //        ciphertext = [data base64EncodedStringWithOptions:0];
        ciphertext = [self parseByte2HexString:buffer :(int)numBytesEncrypted];
        ciphertext = [ciphertext uppercaseString];
    }
    return ciphertext;   
}

- (NSString *) parseByte2HexString:(Byte *) bytes  :(int)len{
    NSString *hexStr = @"";
    if(bytes){
        for(int i=0;i<len;i++) {
            NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff]; ///16进制数
            if([newHexStr length]==1)
                hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr];
            else 
                hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr];
            NSLog(@"%@",hexStr);
        }
    }
    return hexStr;
}

其中kDES_KEY为我定义个一个宏,存储的是进行DES加密的key,可自定义
测试打印:

    NSString *str1 = [@"YH0127" DESString:@"FFNKUIT^%##C<)(&%$FFSQNKOP"];
    ZSLog(@"str1: %@",str1);
image.png

DES解密(待补充)

2.java

DES加解密

package com.example.demo;

import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

/**
 * All right reserved.    
 * DES加密解密类.     
 */
public class DesUtil {
    
    /** 加密、解密key. */
    private static final String PASSWORD_CRYPT_KEY = "FFNKUIT^%##C<)(&%$FFSQNKOP";
    /** 加密算法,可用 DES,DESede,Blowfish. */
    private final static String ALGORITHM = "DES";

    public static void main(String[] args) throws Exception {
        String str = DesUtil.encrypt("YH0127");
        System.out.println("str1: " + str);
        str = DesUtil.decrypt(str);
        System.out.println("str2: " + str);
    }
    
    /**
     * 对数据进行DES加密.
     * @param data 待进行DES加密的数据
     * @return 返回经过DES加密后的数据
     * @throws Exception
     */
    public final static String decrypt(String data) throws Exception {
        return new String(decrypt(hex2byte(data.getBytes()),
                PASSWORD_CRYPT_KEY.getBytes()));
    }
    /**
     * 对用DES加密过的数据进行解密.
     * @param data DES加密数据
     * @return 返回解密后的数据
     * @throws Exception
     */
    public final static String encrypt(String data) throws Exception  {
        return byte2hex(encrypt(data.getBytes("UTF-8"), PASSWORD_CRYPT_KEY
                .getBytes("UTF-8")));
    }
    
    /**
     * 用指定的key对数据进行DES加密.
     * @param data 待加密的数据
     * @param key DES加密的key
     * @return 返回DES加密后的数据
     * @throws Exception
     */
    private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密匙数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
        // 创建一个密匙工厂,然后用它把DESKeySpec转换成
        // 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey securekey = keyFactory.generateSecret(dks);
        // Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        /**
         * If no mode or padding is specified, provider-specific default values for the mode and padding scheme are used. For example, the SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. This means that in the case of the SunJCE provider:
         *
         *
         *     Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");
         * and
         *     Cipher c1 = Cipher.getInstance("DES");
         * are equivalent statements.
         */

        // 用密匙初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
        // 现在,获取数据并加密
        // 正式执行加密操作
        return cipher.doFinal(data);
    }
    
    /**
     * 用指定的key对数据进行DES解密.
     * @param data 待解密的数据
     * @param key DES解密的key
     * @return 返回DES解密后的数据
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        // 从原始密匙数据创建一个DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
        // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
        // 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
        SecretKey securekey = keyFactory.generateSecret(dks);
        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
        // 现在,获取数据并解密
        // 正式执行解密操作
        return cipher.doFinal(data);
    }

    public static byte[] hex2byte(byte[] b) {
        if ((b.length % 2) != 0)
            throw new IllegalArgumentException("长度不是偶数");
        byte[] b2 = new byte[b.length / 2];
        for (int n = 0; n < b.length; n += 2) {
            String item = new String(b, n, 2);
            b2[n / 2] = (byte) Integer.parseInt(item, 16);
        }
        return b2;
    }
    public 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();
    }
}

测试打印:


image.png