首页 > 编程知识 正文

des加密的详细步骤,java实现rsa加密解密文件

时间:2023-05-06 06:42:27 阅读:134090 作者:366

有时候访问群的时候,有一个大神用某个算法加密了一句话,在群里聊天,我真的很羡慕。 因为我不能理解_

一. DES加密算法的简单原理:

很抱歉画得不好,但更基础的原理我暂时不深挖。 密码学本来就是一个大洞,越挖越深。 我不推荐深入学习,因为我不是相关专业。

别胡说,上码:

import Java.security.invalidkeyexception;

import Java.security.nosuchalgorithmexception;

import javax.crypto.badpaddingexception;

import javax.crypto.Cipher;

import javax.crypto.illegalblocksizeexception;

import javax.crypto.nosuchpaddingexception;

import javax.crypto.spec.secret key spec;

import java.util.Base64;

import java.util.Base64.Decoder;

import java.util.Base64.Encoder;

import java.util.Random;

公共类测试des {

publicstaticvoidmain (字符串[ ] args ) {

String plainText='今天吃饭了吗? 如果吃了的话,就可以了。 那证明了你爱我!' ; //明文

//值得注意的是,用现在的getKey ()方法来看

//原始加密密钥的长度越大,越可能生成不同的密文(length个密文线性地增加) )。

//设密文的数量为y,原加密密钥的长度为x,则y=x

如果rawKey中只有一个字符占一个字节,则只生成一个密文

//(经我多次尝试,原始加密密钥“01”有两个字节,但似乎也只生成一个密文。 理由不明)

//我写的这个getKey ()确实是鸡肋) )。

String rawKey='ldl123789654 '; //原始密钥

//指定随机正整数作为加密密钥字节数组中的第一个填充位置

int randomIndex=new Random ().nextint (rawkey.getbytes ) ).length );

string cipher text=test des.desencrypt (plaintext,rawKey,randomIndex );

stringtoplaintext=test des.des decrypt (cipher text,rawKey,randomIndex );

System.out.println (密文: ' cipherText );

System.out.println ('明文: ' toPlainText );

}

publicstaticstringdesencrypt (string plaintext,String rawKey,int randomIndex ) {

String cipherText=null;

try {

//这里采用SecretKeySpec key是想定制钥匙的生产规则

secretkeyspeckey=test des.getkey (rawkey,randomIndex );

//1,获取加密算法的工具类对象

cipher cipher=cipher.getinstance (' des );

//2、初始化加密算法的工具类对象

//opmode是操作模式,加密/解密

//key是转换原始加密密钥的加密密钥SecretKeySpec对象

cipher.init (cipher.encrypt _ mode,key;

//3、用密码算法工具类对象加密明文

byte [ ] do final=cipher.do final (plaintext.getbytes ();

//4、base64编解码器解决编解码后乱码问题的同时,发挥再加密的效果

encoder encoder=base64.get encoder (;

cipher text=encoder.encode tostring (do final );

} catch (nosuchalgorithmexception )|nosuchpaddingexception|illegalblocksizeexception|badpaddingexception

{

e.printStackTrace();

}

return cipherText;

}

public static String desDecrypt(String cipherText, String rawKey, int randomIndex) {

String plainText = null;

try {

SecretKeySpec key = TestDES.getKey(rawKey, randomIndex);

Cipher cipher = Cipher.getInstance("DES");

cipher.init(Cipher.DECRYPT_MODE, key);

Decoder deCoder = Base64.getDecoder();

byte[] deCodeBytes = deCoder.decode(cipherText);

byte[] doFinal = cipher.doFinal(deCodeBytes);

plainText = new String(doFinal);

} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {

e.printStackTrace();

}

return plainText;

}

private static SecretKeySpec getKey(String rawKey, int randomIndex) {

//将用户输入任意长度的原始密匙转换为8个字节的原始密匙

byte[] buffer = new byte[8];

byte[] rawKeyBytes = rawKey.getBytes();

//进行遍历,从一个随机的位置开始循环取值填充到buffer数组里

//若小于8则剩余元素使用byte 0填充,若大于8只取前8个字节

//这只是一种简单的处理方式,当然还有更复杂的处理方式

//for循环结束后可能产生的加密密匙数为rawKeyBytes.length

//即可能产生rawKeyBytes.length个密文(等于可能产生的加密密匙的数目)

for (int i = 0; i < 8 && i < rawKeyBytes.length; i++) {

if (randomIndex >= rawKeyBytes.length) {

randomIndex = 0;

}

buffer[i] = rawKeyBytes[randomIndex++];

}

//DES密匙只支持64位即8个字节的大小,多一个少一个都不行

return new SecretKeySpec(buffer, "DES");

}

}

碰到的问题:在对 byte[] 数组操作(如调用字符串的 getBytes() 方法或者调用算法工具类对象的 doFinal(byte[] arr) 方法)的过程中,若不指定编解码方式,则采用系统默认的编解码方式,我的是中文 win10 系统,默认采用 GBK 编解码。由于 DES 加密算法过于复杂导致最后加密转换后的 byte[] 数组里的字节,很可能在GBK码表上找不到对应的字符(字节丢失),所以在解码时会产生乱码。

​​​​​​

解决思路:找一个码表,在解码后,无论是怎样的二进制字节,都能找到对应的字符。

这样的码表就是 Base64 码表。

Base64码表编解码简要原理:

将会出现的三种情况(只有三种)

1、当字符串所占字节数 % 3 = 0 时,依次取6位(2的6次方,刚好对应Base64码表上的64个字符),刚好拆分完。

如字符串 “ABC” 对应的二进制:

01000001  01000010  01000011

010000 | 01  0100 | 0010  01 | 000011

Q      |       U      |        J       |      D

再将分割出来的二进制数转为十进制数,对照Base64码表可得出: “ABC” --> QUJD。

2、当字符串所占字节数 % 3 = 1 时,依次取 6 位,将会剩下 4 位,缺少的 2 位用 0 补足。

如字符串 “ce” 对应的二进制:

01100011  01100101

011000 | 11  0110 | 0101(00)  ( )表示补足的位

Y      |       2       |      U

对照Base64码表: “ce” --> Y2U=(一个=表示补了00)

3、当字符串所占字节数 % 3 = 2 时,依次取 6 位,将会剩下 2 位,缺少的 4 位用 0 补足。

如字符串“{”对应的二进制:

01111011

011110 | 11(0000)  ( )表示补足的位

e      |      w

对照Base64码表: “{” --> ew==(==表示补了0000)。

好了,该介绍的我都差不多介绍完了,只为了写一个小小的DES加密解密程序,得掌握一些有趣但是略微“偏门”的知识点。天啊,才反应过来,我又钻了一个晚上的牛角尖!

溜了溜了,最后再乱入一个迷你的小蘑菇加密解密的源码:

public class TestCaesarCipher {

public static void main(String[] args) {

String plainText = "Alei&Ali1314@0101_*";

int key = 3;

String cipherText = TestCaesarCipher.encrypt(plainText, key);

System.out.println("密文:" + cipherText);

String toPlainText = TestCaesarCipher.decrypt(cipherText, key);

System.out.println("明文:" + toPlainText);

}

public static String encrypt(String plainText, int key) {

char[] tempCharArr = plainText.toCharArray();

for (int i = 0; i < tempCharArr.length; i++) {

tempCharArr[i] += key;

}

return new String(tempCharArr);

}

public static String decrypt(String cipherText, int key) {

char[] tempCharArr = cipherText.toCharArray();

for (int i = 0; i < tempCharArr.length; i++) {

tempCharArr[i] -= key;

}

return new String(tempCharArr);

}

}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。