程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程解疑 >> 密鑰生成器-java中的 DES 加密與解密

密鑰生成器-java中的 DES 加密與解密

編輯:編程解疑
java中的 DES 加密與解密

DES類

package dao;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

public class DES {

public static String ALGORITHM_DES="DES";       //加密算法的名稱 
public static KeyGenerator keygen;          //密鑰生成器 
public static SecretKey secretKey;      //密鑰 
public static Cipher cipher;        //密碼器
public byte[] bytes;

static{
    Security.addProvider(new com.sun.crypto.provider.SunJCE());
    try{
        keygen=KeyGenerator.getInstance(ALGORITHM_DES);
        secretKey=keygen.generateKey();
        cipher=Cipher.getInstance(ALGORITHM_DES);
    }catch(Exception e){
        e.printStackTrace();
    }
}

//加密
public byte[] encryptor(String str){
    try {
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);    //初始化密碼器,用密鑰 secretKey 進入加密模式
        bytes=cipher.doFinal(str.getBytes());   //加密
    } catch (Exception e) {
        e.printStackTrace();
    }

    return bytes;
}

//解密
public String decryptor(byte[] buff){
    try {
        cipher.init(Cipher.DECRYPT_MODE, secretKey);    //初始化密碼器,用密鑰 secretKey 進入解密模式
        bytes=cipher.doFinal(buff);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return (new String(bytes));
}

}

index.jsp

index.jsp

%>

我的問題:在 index.jsp 頁面裡提交的超鏈接 Demo 提交到 Action ,但是一點擊,後台就報錯:
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.DESCipher.engineDoFinal(DESCipher.java:314)
at javax.crypto.Cipher.doFinal(Cipher.java:2087)
at dao.DES.decryptor(DES.java:44)
at filter.MyFilter.doFilter(MyFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
java.lang.NullPointerException
at java.lang.String.(Unknown Source)
at dao.DES.decryptor(DES.java:48)
at filter.MyFilter.doFilter(MyFilter.java:36)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
解密前:product_id=[B@3242ef

是哪裡寫的不對,請高手指點,我的目的是從 index.jsp 把值(product_id)進行加密,在 Action 裡面取出 加密後的字符串,進行解密,但解密那一塊有問題,可能是 DES 類寫的有問題,請高手幫忙在原有的代碼基礎上修改。成分感激!!

最佳回答:


久等了

 *
 * author: hyb1996 (CSDN)
 * 說明:密匙key的長度必須是8的倍數
 */

package encryption;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.crypto.*;
import javax.crypto.spec.*;

public class DES {

    // 默認密匙
    private static String key = "19491001";
    // 緩沖區大小
    private static final int BufferSize = 1024 * 1024 * 10;

    // 加密解密測試測試
    public static void test() {
        String text = "111測試asdY^&*NN!__s some plaintext!";
        System.out.println("加密前的明文:" + text);

        String cryperText = "";
        try {
            cryperText = toHexString(encrypt(text));
            System.out.println("加密後的明文:" + cryperText);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
            System.out.println("解密後的明文:"
                    + new String(decrypt(convertHexString(cryperText), key),
                            "UTF-8"));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            System.in.read();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // 設置默認密匙
    public static void setKey(String k) {
        key = k;
    }

    // 用指定密匙對密文message解密並返回解密後byte[]
    public static byte[] decrypt(String message, String key) throws Exception {
        return decrypt(message.getBytes("UTF-8"), key);
    }

    // 用默認密匙對密文message解密並返回解密後byte[]
    public static byte[] decrypt(String message) throws Exception {
        return decrypt(message, key);
    }

    // 用指定密匙對密文數據data解密並返回解密後byte[]
    public static byte[] decrypt(byte[] data, String key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        return cipher.doFinal(data);
    }

    // 用指定密匙對密文data從offset開始長度為len的數據解密並返回解密後byte[]
    public static byte[] decrypt(byte[] data, int offset, int len, String key)
            throws Exception {
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        return cipher.doFinal(data, offset, len);
    }

    // 用指定密匙對字符串message加密並返回加密後byte[]
    public static byte[] encrypt(String message, String key) throws Exception {
        return encrypt(message.getBytes("UTF-8"), key);
    }

    // 用默認密匙對字符串message加密並返回加密後byte[]
    public static byte[] encrypt(String message) throws Exception {
        return encrypt(message, key);
    }

    // 用指定密匙對數據data加密並返回加密後byte[]
    public static byte[] encrypt(byte[] data, String key) throws Exception {
        return encrypt(data, 0, data.length, key);
    }

    // 用指定密匙對密文data從offset開始長度為len的數據加密並返回加密後byte[]
    public static byte[] encrypt(byte[] data, int offset, int len, String key)
            throws Exception {
        Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
        IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        return cipher.doFinal(data, offset, len);
    }


    public static byte[] convertHexString(String ss) {
        byte digest[] = new byte[ss.length() / 2];
        for (int i = 0; i < digest.length; i++) {
            String byteString = ss.substring(2 * i, 2 * i + 2);
            int byteValue = Integer.parseInt(byteString, 16);
            digest[i] = (byte) byteValue;
        }

        return digest;
    }

    public static String toHexString(byte b[]) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String plainText = Integer.toHexString(0xff & b[i]);
            if (plainText.length() < 2)
                plainText = "0" + plainText;
            hexString.append(plainText);
        }

        return hexString.toString();
    }

    //用指定密匙key對路徑為path的文件加密並寫入路徑為out的文件中 
    public static void fileEncrypt(String path, String out, String key)
            throws Exception {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        file = new File(out);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[BufferSize];
        byte[] outbuf;
        int size = in.available();
        int done = 0;
        while (in.available() > 0) {
            int len = in.read(buffer);
            outbuf = DES.encrypt(buffer, 0, len, key);
            fos.write(outbuf, 0, outbuf.length);
            done += len;
            System.out.print(100 * (long) done / size);
            System.out.println('%');

        }
        fos.close();
        in.close();
    }

    //用指定密匙key對路徑為path的文件加密並寫入路徑為out的文件中,而且不使用緩沖區
    public static void $fileEncrypt(String path, String out, String key)
            throws Exception {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        file = new File(out);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[in.available()];
        in.read(buffer);
        buffer = DES.encrypt(buffer, key);
        fos.write(buffer, 0, buffer.length);
        fos.close();
        in.close();
    }

    //用指定密匙key將字符串message加密並寫入路勁為out的文件中
    public static void StringEncryptIntoFile(String message, String out,
            String key) throws Exception {
        File file = new File(out);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] data = encrypt(message, key);
        fos.write(data);
        fos.close();
    }

    //用指定密匙key對路徑為path的密文文件解密並寫入路徑為out的文件中 
    public static void fileDecrypt(String path, String out, String key)
            throws Exception {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        file = new File(out);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[BufferSize + 8];
        byte[] outbuf;
        int size = in.available();
        int done = 0;
        while (in.available() > 0) {
            int len = in.read(buffer);
            outbuf = DES.decrypt(buffer, 0, len, key);
            fos.write(outbuf, 0, outbuf.length);
            done += len;
            System.out.print(100 * (long) done / size);
            System.out.println('%');
        }
        fos.close();
        in.close();
    }

    //用指定密匙key對路徑為path的密文文件解密並寫入路徑為out的文件中 ,且不使用緩沖區
    public static void $fileDecrypt(String path, String out, String key)
            throws Exception {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        file = new File(out);
        if (file.exists())
            file.delete();
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[in.available()];
        in.read(buffer);
        buffer = DES.decrypt(buffer, key);
        fos.write(buffer, 0, buffer.length);
        fos.close();
        in.close();
    }

    //用指定密匙key對路徑為path的密文文件解密得到明文字符串並返回
    public static String fileDecrypt(String path, String key) throws Exception {
        File file = new File(path);
        FileInputStream in = new FileInputStream(file);
        byte[] buffer = new byte[BufferSize + 8];
        StringBuffer sb = new StringBuffer();
        int size = in.available();
        int done = 0;
        byte[] outbuf;
        while (in.available() > 0) {
            int len = in.read(buffer);
            outbuf = DES.decrypt(buffer, 0, len, key);
            sb.append(new String(outbuf, 0, outbuf.length, "UTF-8"));
            done += len;
            System.out.print(100 * (long) done / size);
            System.out.println('%');
        }
        in.close();
        return sb.toString();
    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved