和PHP通用的 DES 加解密类

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.Collections;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class DesUtil
{    
    public static void main(String[] args)
    {
        DesUtil des = new DesUtil();
        String res = des.encrypt("adminuser", "1234567", "asdfzxcv");
        System.out.println("密文:");
        System.out.println(res);
        String plaintext = des.decrypt(res, "1234567", "asdfzxcv");
        System.out.println("明文: ");
        System.out.println(plaintext);
    }

    /**
     * 
     * @param plaintext 待加密数据
     * @param key 密钥, 8字节字符串
     * @param iv 初始化随机向量参数,des模式下是长度8个字节的字符串.Java中不指定该参数时, 会使用随机参数加密. php中不使用该参数是, 会抛出警告, 但仍然可以加密
     * @return
     */
    public String encrypt(String plaintext, String key, String iv)
    {
        String result = null;
        try 
        {
            // iv对象
            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
            // 创建密钥对象. 长度不足8个字节时手动补0. 在密钥长度不足时, Java会自动补0, php会自动补\0, 这可能导致加密结果不同
            byte[] nk = new byte[8];
            if(key.getBytes("UTF-8").length < 8)
            {
                int sub = 8 - key.getBytes("UTF-8").length;
                nk = (key + String.join("", Collections.nCopies(sub, 0 + ""))).getBytes("UTF-8");
            }else
            {
                nk = key.getBytes("UTF-8");
            }
            Key sKey = new SecretKeySpec(nk, "DES");
            // 加解密服务类
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            // 指定进行加密
            cipher.init(Cipher.ENCRYPT_MODE, sKey,ivSpec);
            // 执行加密
            byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
            // 返回base64编码过的字符串
            Encoder encoder = Base64.getEncoder();
            result = encoder.encodeToString(ciphertext);
        } catch (NoSuchAlgorithmException e) 
        {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) 
        {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) 
        {
            e.printStackTrace();
        } catch (BadPaddingException e) 
        {
            e.printStackTrace();
        } catch (InvalidKeyException e) 
        {
            e.printStackTrace();
        }catch(Exception e)
        {
            e.printStackTrace();
        }
        return result;
    }
    
    public String decrypt(String cipherText, String key, String iv)
    {
        String result = null;
        Decoder decoder = Base64.getDecoder();
        byte[] cipherByte = decoder.decode(cipherText);
        try 
        {
            IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
            byte[] nk = new byte[8];
            if(key.getBytes("UTF-8").length < 8)
            {
                int sub = 8 - key.getBytes("UTF-8").length;
                nk = (key + String.join("", Collections.nCopies(sub, 0 + ""))).getBytes("UTF-8");
            }else
            {
                nk = key.getBytes("UTF-8");
            }
            Key sKey = new SecretKeySpec(nk, "DES");
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, sKey, ivSpec);
            byte[] plaintext = cipher.doFinal(cipherByte);
            result = new String(plaintext);
        }catch(UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }catch (NoSuchPaddingException e) 
        {
            e.printStackTrace();
        }catch (NoSuchAlgorithmException e) 
        {
            e.printStackTrace();
        }catch (InvalidAlgorithmParameterException e) 
        {
            e.printStackTrace();
        }catch (InvalidKeyException e)
        {
            e.printStackTrace();
        }catch (BadPaddingException e) 
        {
            e.printStackTrace();
        }catch (IllegalBlockSizeException e) 
        {
            e.printStackTrace();
        }
        
        return result;
    }
}

与之对应的 PHP 加解密:

class DES
{
    public function encrypt($plaintext, $key, $iv)
    {
        // 此处采用java的填充规则
        if(strlen($key) < 8)
        {
            $key = $key . str_repeat('0', 8 - strlen($key));
        }
        // 第四个参数设为0, 返回自动填充, 且已经过base64编码都密文
        $ciphertext = openssl_encrypt($plaintext, 'des-cbc', $key, 0, $iv);
        return $ciphertext;
    }

    public function decrypt($ciphertext, $key, $iv)
    {
        if(strlen($key) < 8)
        {
            $key = $key . str_repeat('0', 8 - strlen($key));
        }
        // 解密数据
        $plaintext = openssl_decrypt($ciphertext, 'des-cbc', $key, 0, $iv);
        return $plaintext;
    }
}

猜你喜欢

转载自www.cnblogs.com/fxyy/p/11279489.html
今日推荐