在JAVA中使用DES算法加密数据

        在JDK的javax.crypto 的包中提供了对一些通用算法的加密解密的支持,本文简介一下使用DES算法来对数据加密解密。通常是数据加密方用密钥将数据加密,数据解密方用同样的密钥将数据解密。这个密钥是包含8位byte的一个二进制的文件,加密解密方可以是任何开发语言。

        用JAVA生成一个key并保存到一个二进制文件中去的方法如下:

    public static void saveBytePriveKey(String file) {

        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("DES");

            SecretKey key = keyGen.generateKey();// 生成私钥Key

            FileOutputStream fop = new FileOutputStream(file);
            fop.write(key.getEncoded());
            fop.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }

     从密钥文件中读取内容生成密钥:

    public static SecretKey getBytePriveKey(String file) throws Exception {
        File keyf = new File(file);
        long length = keyf.length();
        byte[] bytes = new byte[(int) length];

        FileInputStream fis = new FileInputStream(keyf);

        // Read in the bytes
        int offset = 0;
        int numRead = 0;

        while (offset < bytes.length && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }
        DESKeySpec dks = new DESKeySpec(bytes);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey key = keyFactory.generateSecret(dks);

        return key;
    }

        对文件进行加密,对文件的操作应该是以流的方式,加密后的数据是一个二进制流,它可能不能被对应到任何编码的String,所以在操作过程中不应该将加密后的byte数据转换为String。将一个文件加密为另一个文件的代码如下:

    public static void encryptFile(String plainFile, String encryptedFile, String keyFile) {
        try {

            SecretKey key = getBytePriveKey(keyFile);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            FileInputStream fis = new FileInputStream(plainFile);
            FileOutputStream fos = new FileOutputStream(encryptedFile);
            crypt(fis, fos, cipher);

            fis.close();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException,
            GeneralSecurityException {
        int blockSize = cipher.getBlockSize();
        int outputSize = cipher.getOutputSize(blockSize);
        System.out.println("blockSize " + blockSize + " outputSize" + outputSize);

        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];

        int inLength = 0;
        boolean more = true;
        while (more) {
            inLength = in.read(inBytes);
            if (inLength == blockSize) {
                int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);
            } else {
                more = false;
            }
        }
        if (inLength > 0)
            outBytes = cipher.doFinal(inBytes, 0, inLength);
        else
            outBytes = cipher.doFinal();
        out.write(outBytes);
    }

      同样,在解密过程中,对数据也应该以流的方式:

    public static void decryptFile(String encryptedFile, String decryptedFile, String keyFile) {
        try {

            SecretKey key = getBytePriveKey(keyFile);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);

            FileInputStream fis = new FileInputStream(encryptedFile);
            FileOutputStream fos = new FileOutputStream(decryptedFile);
            crypt(fis, fos, cipher);

            fis.close();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

        如果是想把很多String一行一行的加密后保存到一个文件,应该先把这些String保存到一个中间文件,然后把中间文件以流的方式读入,以加密文件的方式进行。我尝试着把

加密一个String就写到文件中,但是发现最后解密的时候会有问题。

下面是整个类的源代码:

package com.test.endecrypt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class DESCrypter {

    private static String bytekeyfile = "d://temp//bytekeyfile";

    private static String originalfile = "d://temp//originalfile";
    private static String encryptedfile = "d://temp//encryptedfile";
    private static String decryptedfile = "d://temp//decryptedfile";

    public static void main(String args[]) {

        saveBytePriveKey(bytekeyfile);

        encryptFile(originalfile, encryptedfile, bytekeyfile);

        decryptFile(encryptedfile, decryptedfile, bytekeyfile);

        String[] strings = { "要加密的串 the text to be encrypt", "AAAAAAAAAAA", "要加密的串 the text to be encrypt" };
        encryptStringsTofile(strings, encryptedfile, bytekeyfile);
        decryptFile(encryptedfile, decryptedfile, bytekeyfile);
    }

    public static void encryptFile(String plainFile, String encryptedFile, String keyFile) {
        try {

            SecretKey key = getBytePriveKey(keyFile);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            FileInputStream fis = new FileInputStream(plainFile);
            FileOutputStream fos = new FileOutputStream(encryptedFile);
            crypt(fis, fos, cipher);

            fis.close();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void encryptStringsTofile(String[] strings, String encryptedFile, String keyFile) {
        try {

            SecretKey key = getBytePriveKey(keyFile);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.ENCRYPT_MODE, key);

            FileOutputStream fos = new FileOutputStream(encryptedFile);
            crypt(strings, fos, cipher);

            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void crypt(InputStream in, OutputStream out, Cipher cipher) throws IOException,
            GeneralSecurityException {
        int blockSize = cipher.getBlockSize();
        int outputSize = cipher.getOutputSize(blockSize);
        System.out.println("blockSize " + blockSize + " outputSize" + outputSize);

        byte[] inBytes = new byte[blockSize];
        byte[] outBytes = new byte[outputSize];

        int inLength = 0;
        boolean more = true;
        while (more) {
            inLength = in.read(inBytes);
            if (inLength == blockSize) {
                int outLength = cipher.update(inBytes, 0, blockSize, outBytes);
                out.write(outBytes, 0, outLength);
            } else {
                more = false;
            }
        }
        if (inLength > 0)
            outBytes = cipher.doFinal(inBytes, 0, inLength);
        else
            outBytes = cipher.doFinal();
        out.write(outBytes);
    }

    public static void crypt(String strings[], OutputStream out, Cipher cipher) throws IOException,
            GeneralSecurityException {
        for (String str : strings) {
            byte[] encryptedBytes = encrypt(str + "\r\n", "UTF8", cipher);
            out.write(encryptedBytes);
        }

    }

    public static byte[] encrypt(String in, String strEncode, Cipher cipher) throws IOException,
            GeneralSecurityException {
        byte[] originalBytes = in.getBytes(strEncode);
        byte[] encryptedBytes = cipher.doFinal(originalBytes);

        return encryptedBytes;
    }

    public static void decryptFile(String encryptedFile, String decryptedFile, String keyFile) {
        try {

            SecretKey key = getBytePriveKey(keyFile);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);

            FileInputStream fis = new FileInputStream(encryptedFile);
            FileOutputStream fos = new FileOutputStream(decryptedFile);
            crypt(fis, fos, cipher);

            fis.close();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static SecretKey createSecretKey(String algorithm) {
        // 声明KeyGenerator对象
        KeyGenerator keygen;
        // 声明 密钥对象
        SecretKey deskey = null;
        try {
            // 返回生成指定算法的秘密密钥的 KeyGenerator 对象
            keygen = KeyGenerator.getInstance(algorithm);
            // 生成一个密钥
            deskey = keygen.generateKey();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        // 返回密匙
        return deskey;
    }

    // 把Key 写到文件中:生成一个私有Key对象,保存在文件中
    public static void saveBytePriveKey(String file) {

        try {
            KeyGenerator keyGen = KeyGenerator.getInstance("DES");

            SecretKey key = keyGen.generateKey();// 生成私钥Key

            FileOutputStream fop = new FileOutputStream(file);
            fop.write(key.getEncoded());
            fop.close();
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    public static SecretKey getBytePriveKey(String file) throws Exception {
        File keyf = new File(file);
        long length = keyf.length();
        byte[] bytes = new byte[(int) length];

        FileInputStream fis = new FileInputStream(keyf);

        // Read in the bytes
        int offset = 0;
        int numRead = 0;

        while (offset < bytes.length && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }
        DESKeySpec dks = new DESKeySpec(bytes);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey key = keyFactory.generateSecret(dks);

        return key;
    }

}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用DES算法对学号姓名进行加密Java代码: ```java import javax.crypto.Cipher; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.IvParameterSpec; import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKey; public class DESUtil { private static final String KEY = "12345678"; // 密钥 private static final String IV = "12345678"; // 初始向量 public static String encrypt(String source) throws Exception { DESKeySpec keySpec = new DESKeySpec(KEY.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] encrypted = cipher.doFinal(source.getBytes("UTF-8")); return bytesToHexString(encrypted); } public static String decrypt(String encrypted) throws Exception { byte[] enc = hexStringToBytes(encrypted); DESKeySpec keySpec = new DESKeySpec(KEY.getBytes("UTF-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv); byte[] decrypted = cipher.doFinal(enc); return new String(decrypted, "UTF-8"); } private static String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() < 2) { sb.append('0'); } sb.append(hex); } return sb.toString(); } private static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } } ``` 以上代码使用Java标准库DES算法实现加密和解密。加密和解密过程使用了PKCS5填充,以保证数据块长度为8的倍数。需要注意的是,由于DES算法已经被认为是不安全的算法,因此在实际应用需要使用更加安全的算法来进行数据加密和解密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值