Java常见的加密解密_java 导出 文件流 encode加密-程序员宅基地

技术标签: 加密解密  java  所有文章  

Java常见的加密解密

不可逆加密

介绍

应用场景
一致性验证
MD5 可以为文件传输场景中,提供文件的一致性验证。

例如,文件服务器预先提供一个 MD5 校验值,用户下载完文件以后,用 MD5 算法计算下载文件的 MD5 校验值(如果任何人对文件做了任何改动,这个文件的MD5值就会发生变化),然后通过检查这两个校验值是否一致,就能判断下载的文件是否出错、或者下载的文件是否被篡改了。

现在,利用MD5算法进行文件校验的方法,已经广泛应用到软件下载站、论坛数据库、系统文件安全等方面了。

数字签名
MD5 的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止该段信息被篡改。

例如,在文件“readme.txt”中写入一些内容,并对这个文件进行MD5运算,产生一个MD5值并记录下来,然后可以将这个文件发送给别人,别人如果修改了“readme.txt”文件中的任何内容,我们对这个文件重新计算MD5时,就会发现两个MD5值不同。

在上述过程中,如果再有一个第三方的认证机构介入,那么使用 MD5 还可以防止文件作者的“抵赖”,这就是所谓的数字签名应用。

安全访问认证
MD5 还广泛用于操作系统的登录认证中,如 Unix、各类BSD操作系统登录密码、数字签名等诸多方面。

例如,在Unix操作系统中,用户的密码是经MD5(或其它类似的算法)运算后存储在文件系统中。当用户登录的时候,系统把用户输入的密码进行MD5运算,然后再与保存在文件系统中的MD5值进行比较,从而确定用户输入的密码是否正确。通过这些步骤,操作系统在并不知道用户密码的明文的情况下,就可以确定用户登录系统的合法性,这可以避免用户的密码被具有系统管理员权限的用户窃取。

MD5 将任意长度的“字符串”映射为一个128bit的“字符串”,并且通过该128bit的“字符串”反推原始字符串是困难的,换句话说,即使你看到源程序和算法描述,也很难将一个MD5的值转换回原始的字符串。

md5的用途
密码的加密存储,用户设置密码时,服务端只记录这个密码的MD5,而不记录密码本身,以后验证用户身份时,只需要将用户输入的密码再次做一下MD5后,与记录的MD5作一个比较即可验证其密码的合法性。
数字签名,比如发布一个程序,为了防止别人在你的程序里插入病毒或木马,你可以在发布这个程序的同时,公开这个程序文件的MD5码,这样别人只需要在任何地方下载这个程序后做一次MD5,然后跟公开的这个MD5作一个比较就知道这个程序是否被第三方修改过。
文件完整性验证,比如当下载一个文件时,服务器返回的信息中包括这个文件的md5,在本地下载完毕时进行md5,将两个md5值进行比较,如果一致则说明文件完整没有丢包现象。
文件上传,比如百度云实现的秒传,就是对比你上传的文件md5在百度服务器是否已经存在了,如果存在就不用上传了

MD5

package com.example.ssoserve.utils;


public class Md5 {
    
    //存储小组
    long []groups = null;
    //存储结果
   public String resultMessage="";

    //四个寄存器的初始向量IV,采用小端存储
    static final long A=0x67452301L;
    static final long B=0xefcdab89L;
    static final long C=0x98badcfeL;
    static final long D=0x10325476L;

    //java不支持无符号的基本数据(unsigned),所以选用long数据类型
    private long [] result={
    A,B,C,D};

    static final long T[][] = {
    
            {
    0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
                    0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
                    0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
                    0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821},

            {
    0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
                    0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
                    0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
                    0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a},

            {
    0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
                    0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
                    0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
                    0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665},

            {
    0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
                    0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
                    0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
                    0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}};
    //表示X[k]中的的k取值,决定如何使用消息分组中的字
    static final int k[][] = {
    
            {
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15},
            {
    1, 6,11, 0, 5,10,15, 4, 9,14, 3, 8,13, 2, 7,12},
            {
    5, 8,11,14, 1, 4, 7,10,13, 0, 3, 6, 9,12,15, 2},
            {
    0, 7,14, 5,12, 3,10, 1, 8,15, 6,13, 4,11, 2, 9}};

    //各次迭代中采用的做循环移位的s值
    static final int S[][] = {
    
            {
    7,12,17,22},
            {
    5,9,14,20},
            {
    4,11,16,23},
            {
    6,10,15,21}};

    //4轮循环中使用的生成函数(轮函数)g
    private static long g(int i, long b, long c, long d) {
    
        switch (i) {
    
            case 0:
                return (b & c) | ((~b) & d);
            case 1:
                return (b & d) | (c & (~d));
            case 2:
                return b ^ c ^ d;
            case 3:
                return c ^ (b | (~d));
            default:
                return 0;
        }
    }
    //开始使用MD5加密
    public String start(String message){
    
        //转化为字节数组
        byte [] inputBytes=message.getBytes();
        //6A 61 6E 6b 69 6e 67
        //获取字节数组的长度
        int byteLen = inputBytes.length;
        //得到K值(以bit作单位的message长度)
        long K = (long)(byteLen<<3);
        //完整小组(512bit)(64byte)的个数
        int groupCount = byteLen/64;

        //分块
        for(int i = 0;i < groupCount;i++){
    
            //每次取512bit
            //处理一个分组
            H(divide(inputBytes, i*64));
        }

        //填充
        int rest = byteLen % 64;
        //即将填充的一个分组
        byte [] paddingBytes=new byte[64];
        //原来的尾部数据
        for(int i=0;i<rest;i++)
            paddingBytes[i]=inputBytes[byteLen-rest+i];
        //即小于448bit的情况,先填充100...0再填充K值的低64位
        //此时只会新增一个分组
        if(rest <= 56){
    
            //填充100...0
            if(rest<56){
    
                //填充10000000
                paddingBytes[rest]=(byte)(1<<7);
                //填充00000000
                for(int i=1;i<56-rest;i++) {
    
                    paddingBytes[rest+i]=0;
                }
            }
            //填充K值低64位
            for(int i=0;i<8;i++){
    
                paddingBytes[56+i]=(byte)(K&0xFFL);
                K=K>>8;
            }
            //处理分组
            H(divide(paddingBytes,0));
            //即大于448bit的情况,先填充100...0再填充K值的低64位
            //此时会新增两个分组
        }else{
    
            //填充10000000
            paddingBytes[rest]=(byte)(1<<7);
            //填充00000000
            for(int i=rest+1;i<64;i++) {
    
                paddingBytes[i]=0;
            }
            //处理第一个尾部分组
            H(divide(paddingBytes,0));

            //填充00000000
            for(int i=0;i<56;i++) {
    
                paddingBytes[i]=0;
            }

            //填充低64位
            for(int i=0;i<8;i++){
    
                //这里很关键,使用小端方式,即Byte数组先存储len的低位数据,然后右移len
                paddingBytes[56+i]=(byte)(K&0xFFL);
                K=K>>8;
            }
            //处理第二个尾部分组
            H(divide(paddingBytes,0));
        }
        //将Hash值转换成十六进制的字符串
        //小端方式!
        for(int i=0;i<4;i++){
    
            resultMessage += Long.toHexString(result[i] & 0xFF) +
                    Long.toHexString((result[i] & 0xFF00) >> 8) +
                    Long.toHexString((result[i] & 0xFF0000) >> 16) +
                    Long.toHexString((result[i] & 0xFF000000) >> 24);

        }
        return resultMessage;
    }

    //从inputBytes的index开始取512位,作为新的512bit的分组
    private static long[] divide(byte[] inputBytes,int start){
    
        //存储一整个分组,就是512bit,数组里每个是32bit,就是4字节,为了消除符号位的影响,所以使用long
        long [] group=new long[16];
        for(int i=0;i<16;i++){
    
            //每个32bit由4个字节拼接而来
            //小端的从byte数组到bit恢复方法
            group[i]=byte2unsign(inputBytes[4*i+start])|
                    (byte2unsign(inputBytes[4*i+1+start]))<<8|
                    (byte2unsign(inputBytes[4*i+2+start]))<<16|
                    (byte2unsign(inputBytes[4*i+3+start]))<<24;
        }
        return group;
    }

    //其实byte相当于一个字节的有符号整数,这里不需要符号位,所以把符号位去掉
    public static long byte2unsign(byte b){
    
        return b < 0 ? b & 0x7F + 128 : b;
    }

    // groups[] 中每一个分组512位(64字节)
    // MD5压缩函数
    private void H(long[] groups) {
    
        //缓冲区(寄存器)数组
        long a = result[0], b = result[1], c = result[2], d = result[3];
        //四轮循环
        for(int n = 0; n < 4; n++) {
    
            //16轮迭代
            for(int i = 0; i < 16; i++) {
    
                result[0] += (g(n, result[1], result[2], result[3])&0xFFFFFFFFL) + groups[k[n][i]] + T[n][i];
                result[0] = result[1] + ((result[0]&0xFFFFFFFFL)<< S[n][i % 4] | ((result[0]&0xFFFFFFFFL) >>> (32 - S[n][i % 4])));
                //循环轮换
                long temp = result[3];
                result[3] = result[2];
                result[2] = result[1];
                result[1] = result[0];
                result[0] = temp;
            }
        }
        //加入之前计算的结果
        result[0] += a;
        result[1] += b;
        result[2] += c;
        result[3] += d;
        //防止溢出
        for(int n = 0; n < 4 ; n++) {
    
            result[n] &=0xFFFFFFFFL;
        }
    }

    public static void main(String []args){
    
        Md5 md=new Md5();

        String message = "helloMD5";
        System.out.println("明文:" + message);
        System.out.println("小写的密文:" + md.start(message));
        System.out.println("大写的密文: " + md.resultMessage.toUpperCase());
//        明文:helloMD5
//        小写的密文:3ed9e5f6855dbcdbcd95ac6c4fe0c0a5
//        大写的密文: 3ED9E5F6855DBCDBCD95AC6C4FE0C0A5
    }
}


前端MD5

jQuery.md5.js

(function($){
    
    var rotateLeft = function(lValue, iShiftBits) {
    
        return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
    }
    var addUnsigned = function(lX, lY) {
    
        var lX4, lY4, lX8, lY8, lResult;
        lX8 = (lX & 0x80000000);
        lY8 = (lY & 0x80000000);
        lX4 = (lX & 0x40000000);
        lY4 = (lY & 0x40000000);
        lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
        if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
        if (lX4 | lY4) {
    
            if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
            else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
        } else {
    
            return (lResult ^ lX8 ^ lY8);
        }
    }
    var F = function(x, y, z) {
    
        return (x & y) | ((~ x) & z);
    }
    var G = function(x, y, z) {
    
        return (x & z) | (y & (~ z));
    }
    var H = function(x, y, z) {
    
        return (x ^ y ^ z);
    }
    var I = function(x, y, z) {
    
        return (y ^ (x | (~ z)));
    }
    var FF = function(a, b, c, d, x, s, ac) {
    
        a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var GG = function(a, b, c, d, x, s, ac) {
    
        a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var HH = function(a, b, c, d, x, s, ac) {
    
        a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var II = function(a, b, c, d, x, s, ac) {
    
        a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
        return addUnsigned(rotateLeft(a, s), b);
    };
    var convertToWordArray = function(string) {
    
        var lWordCount;
        var lMessageLength = string.length;
        var lNumberOfWordsTempOne = lMessageLength + 8;
        var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
        var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
        var lWordArray = Array(lNumberOfWords - 1);
        var lBytePosition = 0;
        var lByteCount = 0;
        while (lByteCount < lMessageLength) {
    
            lWordCount = (lByteCount - (lByteCount % 4)) / 4;
            lBytePosition = (lByteCount % 4) * 8;
            lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
            lByteCount++;
        }
        lWordCount = (lByteCount - (lByteCount % 4)) / 4;
        lBytePosition = (lByteCount % 4) * 8;
        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
        lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
        lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
        return lWordArray;
    };
    var wordToHex = function(lValue) {
    
        var WordToHexValue = "", WordToHexValueTemp = "", lByte, lCount;
        for (lCount = 0; lCount <= 3; lCount++) {
    
            lByte = (lValue >>> (lCount * 8)) & 255;
            WordToHexValueTemp = "0" + lByte.toString(16);
            WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
        }
        return WordToHexValue;
    };
    var uTF8Encode = function(string) {
    
        string = string.replace(/\x0d\x0a/g, "\x0a");
        var output = "";
        for (var n = 0; n < string.length; n++) {
    
            var c = string.charCodeAt(n);
            if (c < 128) {
    
                output += String.fromCharCode(c);
            } else if ((c > 127) && (c < 2048)) {
    
                output += String.fromCharCode((c >> 6) | 192);
                output += String.fromCharCode((c & 63) | 128);
            } else {
    
                output += String.fromCharCode((c >> 12) | 224);
                output += String.fromCharCode(((c >> 6) & 63) | 128);
                output += String.fromCharCode((c & 63) | 128);
            }
        }
        return output;
    };
    $.extend({
    
        md5: function(string) {
    
            var x = Array();
            var k, AA, BB, CC, DD, a, b, c, d;
            var S11=7, S12=12, S13=17, S14=22;
            var S21=5, S22=9 , S23=14, S24=20;
            var S31=4, S32=11, S33=16, S34=23;
            var S41=6, S42=10, S43=15, S44=21;
            string = uTF8Encode(string);
            x = convertToWordArray(string);
            a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
            for (k = 0; k < x.length; k += 16) {
    
                AA = a; BB = b; CC = c; DD = d;
                a = FF(a, b, c, d, x[k+0],  S11, 0xD76AA478);
                d = FF(d, a, b, c, x[k+1],  S12, 0xE8C7B756);
                c = FF(c, d, a, b, x[k+2],  S13, 0x242070DB);
                b = FF(b, c, d, a, x[k+3],  S14, 0xC1BDCEEE);
                a = FF(a, b, c, d, x[k+4],  S11, 0xF57C0FAF);
                d = FF(d, a, b, c, x[k+5],  S12, 0x4787C62A);
                c = FF(c, d, a, b, x[k+6],  S13, 0xA8304613);
                b = FF(b, c, d, a, x[k+7],  S14, 0xFD469501);
                a = FF(a, b, c, d, x[k+8],  S11, 0x698098D8);
                d = FF(d, a, b, c, x[k+9],  S12, 0x8B44F7AF);
                c = FF(c, d, a, b, x[k+10], S13, 0xFFFF5BB1);
                b = FF(b, c, d, a, x[k+11], S14, 0x895CD7BE);
                a = FF(a, b, c, d, x[k+12], S11, 0x6B901122);
                d = FF(d, a, b, c, x[k+13], S12, 0xFD987193);
                c = FF(c, d, a, b, x[k+14], S13, 0xA679438E);
                b = FF(b, c, d, a, x[k+15], S14, 0x49B40821);
                a = GG(a, b, c, d, x[k+1],  S21, 0xF61E2562);
                d = GG(d, a, b, c, x[k+6],  S22, 0xC040B340);
                c = GG(c, d, a, b, x[k+11], S23, 0x265E5A51);
                b = GG(b, c, d, a, x[k+0],  S24, 0xE9B6C7AA);
                a = GG(a, b, c, d, x[k+5],  S21, 0xD62F105D);
                d = GG(d, a, b, c, x[k+10], S22, 0x2441453);
                c = GG(c, d, a, b, x[k+15], S23, 0xD8A1E681);
                b = GG(b, c, d, a, x[k+4],  S24, 0xE7D3FBC8);
                a = GG(a, b, c, d, x[k+9],  S21, 0x21E1CDE6);
                d = GG(d, a, b, c, x[k+14], S22, 0xC33707D6);
                c = GG(c, d, a, b, x[k+3],  S23, 0xF4D50D87);
                b = GG(b, c, d, a, x[k+8],  S24, 0x455A14ED);
                a = GG(a, b, c, d, x[k+13], S21, 0xA9E3E905);
                d = GG(d, a, b, c, x[k+2],  S22, 0xFCEFA3F8);
                c = GG(c, d, a, b, x[k+7],  S23, 0x676F02D9);
                b = GG(b, c, d, a, x[k+12], S24, 0x8D2A4C8A);
                a = HH(a, b, c, d, x[k+5],  S31, 0xFFFA3942);
                d = HH(d, a, b, c, x[k+8],  S32, 0x8771F681);
                c = HH(c, d, a, b, x[k+11], S33, 0x6D9D6122);
                b = HH(b, c, d, a, x[k+14], S34, 0xFDE5380C);
                a = HH(a, b, c, d, x[k+1],  S31, 0xA4BEEA44);
                d = HH(d, a, b, c, x[k+4],  S32, 0x4BDECFA9);
                c = HH(c, d, a, b, x[k+7],  S33, 0xF6BB4B60);
                b = HH(b, c, d, a, x[k+10], S34, 0xBEBFBC70);
                a = HH(a, b, c, d, x[k+13], S31, 0x289B7EC6);
                d = HH(d, a, b, c, x[k+0],  S32, 0xEAA127FA);
                c = HH(c, d, a, b, x[k+3],  S33, 0xD4EF3085);
                b = HH(b, c, d, a, x[k+6],  S34, 0x4881D05);
                a = HH(a, b, c, d, x[k+9],  S31, 0xD9D4D039);
                d = HH(d, a, b, c, x[k+12], S32, 0xE6DB99E5);
                c = HH(c, d, a, b, x[k+15], S33, 0x1FA27CF8);
                b = HH(b, c, d, a, x[k+2],  S34, 0xC4AC5665);
                a = II(a, b, c, d, x[k+0],  S41, 0xF4292244);
                d = II(d, a, b, c, x[k+7],  S42, 0x432AFF97);
                c = II(c, d, a, b, x[k+14], S43, 0xAB9423A7);
                b = II(b, c, d, a, x[k+5],  S44, 0xFC93A039);
                a = II(a, b, c, d, x[k+12], S41, 0x655B59C3);
                d = II(d, a, b, c, x[k+3],  S42, 0x8F0CCC92);
                c = II(c, d, a, b, x[k+10], S43, 0xFFEFF47D);
                b = II(b, c, d, a, x[k+1],  S44, 0x85845DD1);
                a = II(a, b, c, d, x[k+8],  S41, 0x6FA87E4F);
                d = II(d, a, b, c, x[k+15], S42, 0xFE2CE6E0);
                c = II(c, d, a, b, x[k+6],  S43, 0xA3014314);
                b = II(b, c, d, a, x[k+13], S44, 0x4E0811A1);
                a = II(a, b, c, d, x[k+4],  S41, 0xF7537E82);
                d = II(d, a, b, c, x[k+11], S42, 0xBD3AF235);
                c = II(c, d, a, b, x[k+2],  S43, 0x2AD7D2BB);
                b = II(b, c, d, a, x[k+9],  S44, 0xEB86D391);
                a = addUnsigned(a, AA);
                b = addUnsigned(b, BB);
                c = addUnsigned(c, CC);
                d = addUnsigned(d, DD);
            }
            var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
            return tempValue.toLowerCase();
        }
    });
})(jQuery);
<script src="jquery-3.4.1.js"></script>
<script src="jQuery.md5.js"></script>
<script>
    //加密
    alert($.md5("1234"))
</script>

SHA1



public class SHA1 {
    

    private static final boolean hexcase = false;
    private static final String b64pad = "=";
    private static final int chrsz = 8;

    // 得到字符串SHA-1值的方法
    public static String hex_sha1(String s) {
    
        s = (s == null) ? "" : s;
        return binb2hex(core_sha1(str2binb(s), s.length() * chrsz));
    }

    public static String b64_hmac_sha1(String key, String data) {
    
        return binb2b64(core_hmac_sha1(key, data));
    }

    public static String b64_sha1(String s) {
    
        s = (s == null) ? "" : s;
        return binb2b64(core_sha1(str2binb(s), s.length() * chrsz));
    }

    private static String binb2b64(int[] binarray) {
    
        String tab = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/";
        String str = "";
        binarray = strechbinarray(binarray, binarray.length * 4);

        for (int i = 0; i < binarray.length * 4; i += 3) {
    
            int triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xff) << 16)
                    | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xff) << 8)
                    | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xff);

            for (int j = 0; j < 4; j++) {
    
                if (i * 8 + j * 6 > binarray.length * 32) {
    
                    str += b64pad;
                } else {
    
                    str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3f);
                }
            }
        }

        return cleanb64str(str);
    }

    private static String binb2hex(int[] binarray) {
    
        String hex_tab = hexcase ? "0123456789abcdef" : "0123456789abcdef";
        String str = "";

        for (int i = 0; i < binarray.length * 4; i++) {
    
            char a = (char) hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xf);
            char b = (char) hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xf);
            str += (new Character(a).toString() + new Character(b).toString());
        }

        return str;
    }

    private static String binb2str(int[] bin) {
    
        String str = "";
        int mask = (1 << chrsz) - 1;

        for (int i = 0; i < bin.length * 32; i += chrsz) {
    
            str += (char) ((bin[i >> 5] >>> (24 - i % 32)) & mask);
        }

        return str;
    }

    private static int bit_rol(int num, int cnt) {
    
        return (num << cnt) | (num >>> (32 - cnt));
    }

    private static String cleanb64str(String str) {
    
        str = (str == null) ? "" : str;
        int len = str.length();

        if (len <= 1) {
    
            return str;
        }

        char trailchar = str.charAt(len - 1);
        String trailstr = "";

        for (int i = len - 1; i >= 0 && str.charAt(i) == trailchar; i--) {
    
            trailstr += str.charAt(i);
        }

        return str.substring(0, str.indexOf(trailstr));
    }

    private static int[] complete216(int[] oldbin) {
    
        if (oldbin.length >= 16) {
    
            return oldbin;
        }

        int[] newbin = new int[16 - oldbin.length];

        for (int i = 0; i < newbin.length; newbin[i] = 0, i++)
            ;

        return concat(oldbin, newbin);
    }

    private static int[] concat(int[] oldbin, int[] newbin) {
    
        int[] retval = new int[oldbin.length + newbin.length];

        for (int i = 0; i < (oldbin.length + newbin.length); i++) {
    
            if (i < oldbin.length) {
    
                retval[i] = oldbin[i];
            } else {
    
                retval[i] = newbin[i - oldbin.length];
            }
        }

        return retval;
    }

    private static int[] core_hmac_sha1(String key, String data) {
    
        key = (key == null) ? "" : key;
        data = (data == null) ? "" : data;
        int[] bkey = complete216(str2binb(key));

        if (bkey.length > 16) {
    
            bkey = core_sha1(bkey, key.length() * chrsz);
        }

        int[] ipad = new int[16];
        int[] opad = new int[16];

        for (int i = 0; i < 16; ipad[i] = 0, opad[i] = 0, i++)
            ;

        for (int i = 0; i < 16; i++) {
    
            ipad[i] = bkey[i] ^ 0x36363636;
            opad[i] = bkey[i] ^ 0x5c5c5c5c;
        }

        int[] hash = core_sha1(concat(ipad, str2binb(data)), 512 + data.length() * chrsz);

        return core_sha1(concat(opad, hash), 512 + 160);
    }

    private static int[] core_sha1(int[] x, int len) {
    
        int size = (len >> 5);
        x = strechbinarray(x, size);
        x[len >> 5] |= 0x80 << (24 - len % 32);
        size = ((len + 64 >> 9) << 4) + 15;
        x = strechbinarray(x, size);
        x[((len + 64 >> 9) << 4) + 15] = len;

        int[] w = new int[80];
        int a = 1732584193;
        int b = -271733879;
        int c = -1732584194;
        int d = 271733878;
        int e = -1009589776;

        for (int i = 0; i < x.length; i += 16) {
    
            int olda = a;
            int oldb = b;
            int oldc = c;
            int oldd = d;
            int olde = e;

            for (int j = 0; j < 80; j++) {
    
                if (j < 16) {
    
                    w[j] = x[i + j];
                } else {
    
                    w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
                }

                int t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)));

                e = d;
                d = c;
                c = rol(b, 30);
                b = a;
                a = t;
            }

            a = safe_add(a, olda);
            b = safe_add(b, oldb);
            c = safe_add(c, oldc);
            d = safe_add(d, oldd);
            e = safe_add(e, olde);
        }

        int[] retval = new int[5];

        retval[0] = a;
        retval[1] = b;
        retval[2] = c;
        retval[3] = d;
        retval[4] = e;

        return retval;
    }

    private static void dotest() {
    
        String key = "key";
        String data = "data";
        System.out.println("hex_sha1(" + data + ")=" + hex_sha1(data));
        System.out.println("b64_sha1(" + data + ")=" + b64_sha1(data));
        System.out.println("str_sha1(" + data + ")=" + str_sha1(data));
        System.out.println("hex_hmac_sha1(" + key + "," + data + ")=" + hex_hmac_sha1(key, data));
        System.out.println("b64_hmac_sha1(" + key + "," + data + ")=" + b64_hmac_sha1(key, data));
        System.out.println("str_hmac_sha1(" + key + "," + data + ")=" + str_hmac_sha1(key, data));
    }

    public static String hex_hmac_sha1(String key, String data) {
    
        return binb2hex(core_hmac_sha1(key, data));
    }

    private static int rol(int num, int cnt) {
    
        return (num << cnt) | (num >>> (32 - cnt));
    }

    private static int safe_add(int x, int y) {
    
        int lsw = (int) (x & 0xffff) + (int) (y & 0xffff);
        int msw = (x >> 16) + (y >> 16) + (lsw >> 16);

        return (msw << 16) | (lsw & 0xffff);
    }

    private static int sha1_ft(int t, int b, int c, int d) {
    
        if (t < 20)
            return (b & c) | ((~b) & d);

        if (t < 40)
            return b ^ c ^ d;

        if (t < 60)
            return (b & c) | (b & d) | (c & d);

        return b ^ c ^ d;
    }

    private static int sha1_kt(int t) {
    
        return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514;
    }

    private static boolean sha1_vm_test() {
    
        return hexcase ? hex_sha1("abc").equals("a9993e364706816aba3e25717850c26c9cd0d89d") : hex_sha1("abc").equals(
                "a9993e364706816aba3e25717850c26c9cd0d89d");
    }

    public static String str_hmac_sha1(String key, String data) {
    
        return binb2str(core_hmac_sha1(key, data));
    }

    public static String str_sha1(String s) {
    
        s = (s == null) ? "" : s;

        return binb2str(core_sha1(str2binb(s), s.length() * chrsz));
    }

    private static int[] str2binb(String str) {
    
        str = (str == null) ? "" : str;

        int[] tmp = new int[str.length() * chrsz];
        int mask = (1 << chrsz) - 1;

        for (int i = 0; i < str.length() * chrsz; i += chrsz) {
    
            tmp[i >> 5] |= ((int) (str.charAt(i / chrsz)) & mask) << (24 - i % 32);
        }

        int len = 0;
        for (int i = 0; i < tmp.length && tmp[i] != 0; i++, len++)
            ;

        int[] bin = new int[len];

        for (int i = 0; i < len; i++) {
    
            bin[i] = tmp[i];
        }

        return bin;
    }

    private static int[] strechbinarray(int[] oldbin, int size) {
    
        int currlen = oldbin.length;

        if (currlen >= size + 1) {
    
            return oldbin;
        }

        int[] newbin = new int[size + 1];
        for (int i = 0; i < size; newbin[i] = 0, i++)
            ;

        for (int i = 0; i < currlen; i++) {
    
            newbin[i] = oldbin[i];
        }

        return newbin;
    }

    public static void main(String[] args) {
    
        System.out.println("admin的SHA1的值为:" + hex_sha1("123") + ",length=" + hex_sha1("admin").length());
    }
}


比较依据 MD5 SHA1
代表 信息摘要 安全哈希算法
信息摘要的长度 128位 160位
识别原始消息将需要 2 的128次幂操作 2的160次幂操作
查找两条生成相同消息摘要的消息 需要2的64次幂操作 需要2的80次幂操作
安全 较差的 中等
速度 快速

可逆加密

介绍

对称加密解密

非对称加密解密

非对称 就是 商家 生成 公钥 和私钥
公钥 给用户 让用户进行加密 后将加密后的 密文 发给商家
商家在利用私钥进行解密 (有效防止窃取)

对称加密:双方使用的同一个密钥,既可以加密又可以解密,这种加密方法称为对称加密,也称为单密钥加密。

优点:速度快,对称性加密通常在消息发送方需要加密大量数据时使用,算法公开、计算量小、加密速度快、加密效率高。

缺点:在数据传送前,发送方和接收方必须商定好秘钥,然后 使双方都能保存好秘钥。其次如果一方的秘钥被泄露,那么加密信息也就不安全了。另外,每对用户每次使用对称加密算法时,都需要使用其他人不知道的唯一秘 钥,这会使得收、发双方所拥有的钥匙数量巨大,密钥管理成为双方的负担。

在对称加密算法中常用的算法有:DES、AES等。

AES:密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节

DES:密钥的长度64位,8个字节。

非对称加密:一对密钥由公钥和私钥组成(可以使用很多对密钥)。私钥解密公钥加密数据,公钥解密私钥加密数据(私钥公钥可以互相加密解密)。

私钥只能由一方保管,不能外泄。公钥可以交给任何请求方。

在非对称加密算法中常用的算法有:

RSA、Elgamal、背包算法、Rabin、Diffie-Hellman、ECC(椭圆曲线加密算法)。
使用最广泛的是RSA算法,Elgamal是另一种常用的非对称加密算法。

缺点:速度较慢

优点:安全

对称加密解密

AES

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class AESUtil {
    
    public static final String AES = "AES";
    public static final String charset = "UTF-8"; // 编码格式
    public static final int keysizeAES = 128;

    private static AESUtil instance;

    private AESUtil() {
    
    }

    // 单例
    public static AESUtil getInstance() {
    
        if (instance == null) {
    
            synchronized (AESUtil.class) {
    
                if (instance == null) {
    
                    instance = new AESUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 使用 AES 进行加密
     */
    public String encode(String res, String key) {
    
        return keyGeneratorES(res, AES, key, keysizeAES, true);
    }

    /**
     * 使用 AES 进行解密
     */
    public String decode(String res, String key) {
    
        return keyGeneratorES(res, AES, key, keysizeAES, false);
    }

    // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
    private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
    
        try {
    
            KeyGenerator kg = KeyGenerator.getInstance(algorithm);
            if (keysize == 0) {
    
                byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                kg.init(new SecureRandom(keyBytes));
            } else if (key == null) {
    
                kg.init(keysize);
            } else {
    
                byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                kg.init(keysize, new SecureRandom(keyBytes));
            }
            SecretKey sk = kg.generateKey();
            SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
            Cipher cipher = Cipher.getInstance(algorithm);
            if (isEncode) {
    
                cipher.init(Cipher.ENCRYPT_MODE, sks);
                byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                return parseByte2HexStr(cipher.doFinal(resBytes));
            } else {
    
                cipher.init(Cipher.DECRYPT_MODE, sks);
                return new String(cipher.doFinal(parseHexStr2Byte(res)));
            }
        } catch (Exception e) {
    
            e.printStackTrace();
        }
        return null;
    }

    // 将二进制转换成16进制
    private String parseByte2HexStr(byte buf[]) {
    
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
    
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
    
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    // 将16进制转换为二进制
    private byte[] parseHexStr2Byte(String hexStr) {
    
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
    
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    public static void main(String[] args) {
    
        AESUtil instance = AESUtil.getInstance();
        //加密
        String jiami = instance.encode("hu867682752", "aaa");
        System.out.println(jiami);
        //解密
        String jiemi= instance.decode(jiami, "aaa");
        System.out.println(jiemi);

    }
}
DES
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

public class DESUtil {
    
    public static final String DES = "DES";
    public static final String charset = "UTF-8"; // 编码格式;默认null为GBK
    public static final int keysizeDES = 0;

    private static DESUtil instance;

    private DESUtil() {
    
    }

    // 单例
    public static DESUtil getInstance() {
    
        if (instance == null) {
    
            synchronized (DESUtil.class) {
    
                if (instance == null) {
    
                    instance = new DESUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 使用 DES 进行加密
     */
    public String encode(String res, String key) {
    
        return keyGeneratorES(res, DES, key, keysizeDES, true);
    }

    /**
     * 使用 DES 进行解密
     */
    public String decode(String res, String key) {
    
        return keyGeneratorES(res, DES, key, keysizeDES, false);
    }

    // 使用KeyGenerator双向加密,DES/AES,注意这里转化为字符串的时候是将2进制转为16进制格式的字符串,不是直接转,因为会出错
    private String keyGeneratorES(String res, String algorithm, String key, int keysize, boolean isEncode) {
    
        try {
    
            KeyGenerator kg = KeyGenerator.getInstance(algorithm);
            if (keysize == 0) {
    
                byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                kg.init(new SecureRandom(keyBytes));
            } else if (key == null) {
    
                kg.init(keysize);
            } else {
    
                byte[] keyBytes = charset == null ? key.getBytes() : key.getBytes(charset);
                kg.init(keysize, new SecureRandom(keyBytes));
            }
            SecretKey sk = kg.generateKey();
            SecretKeySpec sks = new SecretKeySpec(sk.getEncoded(), algorithm);
            Cipher cipher = Cipher.getInstance(algorithm);
            if (isEncode) {
    
                cipher.init(Cipher.ENCRYPT_MODE, sks);
                byte[] resBytes = charset == null ? res.getBytes() : res.getBytes(charset);
                return parseByte2HexStr(cipher.doFinal(resBytes));
            } else {
    
                cipher.init(Cipher.DECRYPT_MODE, sks);
                return new String(cipher.doFinal(parseHexStr2Byte(res)));
            }
        } catch (Exception e) {
    
            e.printStackTrace();
        }
        return null;
    }

    // 将二进制转换成16进制
    private String parseByte2HexStr(byte buf[]) {
    
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
    
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
    
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    // 将16进制转换为二进制
    private byte[] parseHexStr2Byte(String hexStr) {
    
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
    
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    public static void main(String[] args) {
    
        DESUtil instance= DESUtil.getInstance();
          String jiami=  instance.encode("12345abc67","abc");
          System.out.println(jiami);
          String jiemi=instance.decode(jiami,"abc");
          System.out.println(jiemi);

    }
}
XOR

public class XORUtil {
    
    private static XORUtil instance;

    private XORUtil() {
    
    }

    // 单例
    public static XORUtil getInstance() {
    
        if (instance == null) {
    
            synchronized (XORUtil.class) {
    
                if (instance == null) {
    
                    instance = new XORUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 对一个数字进行异或加解密
     */
    public int code(int res, String key) {
    
        return res ^ key.hashCode();
    }

    /**
     * 异或加密
     */
    public String encode(String res, String key) {
    
        byte[] bs = res.getBytes();
        for (int i = 0; i < bs.length; i++) {
    
            bs[i] = (byte) ((bs[i]) ^ key.hashCode());
        }
        return parseByte2HexStr(bs);
    }

    /**
     * 异或解密
     */
    public String decode(String res, String key) {
    
        byte[] bs = parseHexStr2Byte(res);
        for (int i = 0; i < bs.length; i++) {
    
            bs[i] = (byte) ((bs[i]) ^ key.hashCode());
        }
        return new String(bs);
    }

    // 将二进制转换成16进制
    private String parseByte2HexStr(byte buf[]) {
    
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
    
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
    
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    // 将16进制转换为二进制
    private byte[] parseHexStr2Byte(String hexStr) {
    
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
    
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

    public static void main(String[] args) {
    

        XORUtil  instance=  XORUtil.getInstance();
       String jiami= instance.encode("124ff","abc");
        System.out.println(jiami);
        String jiemi = instance.decode(jiami,"abc");
        System.out.println(jiemi);
//针对 纯数字 进行加密  和解密
        int num_jiami= instance.code(543,"abv");
        System.out.println(num_jiami);
        int num_jiemi= instance.code(num_jiami,"abv");
        System.out.println(num_jiemi);

    }
}

非对称

RSA后端工具

import org.apache.commons.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yihur
 * @description RSA加密
 * @date 2019/4/3
 */
public class RSAUtils {
    

//前端使用方法
//<script src="js/jsencrypt.js"></script>
//    function encryptRequest( text) {
    
//        var encrypt=new JSEncrypt();
//        encrypt.setPrivateKey("公秘钥");
			//生成密文
//        alert(encrypt.encrypt(text))
//    }

    /**
     * 用于封装随机产生的公钥与私钥
     *
     * @author yihur
     * @date 2019/4/4
     * @param
     * @return
     */
    private static Map<Integer, String> keyMap = new HashMap<>();




    /**
     * 随机生成密钥对
     *
     * @param
     * @return void
     * @author yihur
     * @date 2019/4/4
     */
    public static void genKeyPair() {
    
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = null;
        try {
    
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
    
            e.printStackTrace();

        }
        // 初始化密钥对生成器,密钥大小为96-1024位
        assert keyPairGen != null;
        keyPairGen.initialize(1024, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 将公钥和私钥保存到Map
        keyMap.put(0, publicKeyString);  //0表示公钥
        keyMap.put(1, privateKeyString);  //1表示私钥
    }

    /**
     * RSA公钥加密
     *
     * @param str       加密字符串
     * @param publicKey 公钥
     * @return 密文
     */
    public static String encrypt(String str, String publicKey) {
    
        //base64编码的公钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = null;
        String outStr = null;
        try {
    
            pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
        } catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
    
            e.printStackTrace();

        }
        //RSA加密
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str        加密字符串
     * @param privateKey 私钥
     * @return 铭文
     */
    public static String decrypt(String str, String privateKey) {
    
        //64位解码加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //base64编码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = null;
        //RSA解密
        Cipher cipher = null;
        String outStr = null;
        try {
    
            priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
    
            e.printStackTrace();

        }
        return outStr;
    }


    public static void main(String[] args) {
    
        //生成公钥和私钥
        genKeyPair();
        String  publicKey=keyMap.get(0);
        String  privateKey=keyMap.get(1);
        //加密字符串
        String message = "df723820";
        System.out.println("随机生成的公钥为:" + publicKey);
        System.out.println("随机生成的私钥为:" + privateKey);
        //加密 生成密文
        String messageEn = encrypt(message, publicKey);
        System.out.println("加密后的字符串为:" + messageEn);
        //解密
        String messageDe = decrypt(messageEn, privateKey);
        System.out.println("还原后的字符串为:" + messageDe);
    }

}
RSA 前端工具

jsencrypt.js

链接:https://pan.baidu.com/s/1p4bTF8w_nw5pBieIr_EFyA
提取码:1234

前端-后端 使用RSA

使用步骤

后端 生成公钥和私秘钥
前端 利用公秘钥 生成密文 传递给后端
后端在 利用私秘钥 解析密文

当然前端也是可以生成公钥和私秘钥 但是不安全 一般都是交给后端

公秘钥和私密钥生成

前端
生成公秘钥和私密钥 和使用

    var encrypt=new JSEncrypt();
    var  publicKey = encrypt.getPublicKey();
    var privateKey = encrypt.getPrivateKey();
    alert("公钥\n"+publicKey)
    alert("私钥\n"+privateKey)


//前端使用方法
<script src="js/jsencrypt.js"></script>
	<script>
       function encryptRequest( text) {
    
        var encrypt=new JSEncrypt();
       encrypt.setPrivateKey("公秘钥");
			//生成密文
       alert(encrypt.encrypt(text))
    }
    
    </script>

后端

生成公秘钥和私密钥 和使用



 //生成公钥和私钥
   public static void main(String[] args) {
    
        //生成公钥和私钥
        genKeyPair();
        String  publicKey=keyMap.get(0);
        String  privateKey=keyMap.get(1);
        //加密字符串
        String message = "df723820";
        System.out.println("随机生成的公钥为:" + publicKey);
        System.out.println("随机生成的私钥为:" + privateKey);
        //利用公秘钥加密 生成密文   (这一步可以放到前端  )
        String messageEn = encrypt(message, publicKey);
        System.out.println("加密后的字符串为:" + messageEn);
        //解密  (传来的密文   利用私钥 解析出来 )
        String messageDe = decrypt(messageEn, privateKey);
        System.out.println("还原后的字符串为:" + messageDe);
    }



点赞 -收藏-关注-便于以后复习和收到最新内容
有其他问题在评论区讨论-或者私信我-收到会在第一时间回复
如有侵权,请私信联系我
感谢,配合,希望我的努力对你有帮助^_^

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45203607/article/details/120238328

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法