Java安全之安全加密算法

摘要:
Java安全加密算法0x00前言本文介绍一些常见的加密算法。事实上,在此之前,我们对算法了解不多。我们还来谈谈加密算法在安全领域中的作用。代码示例:packagecom。演示;importcom.sun.org.apache.xerces.internal.impl.dv.util。HexBin;importjava.security。消息摘要;importjava.security。NoSuchAlgorithmException;PublicclassMD5demo{privatestaticStringname=“xiaoming”;publicstaticvoidmaintainrowsNoSuchAlgorithmException{MessageDigestmd5=MessageDigest.getInstance;//将摘要算法对象设置为返回byte[]digest=md5.digest;//计算哈希值System.out.println;//输出哈希结果}}SHA安全哈希算法是密码哈希函数家族和FIPS认证的安全哈希算法。BASE64由于BASE64的加密和解密算法是公开的,因此加密数据没有安全性。
Java安全之安全加密算法

0x00 前言

本篇文来谈谈关于常见的一些加密算法,其实在此之前,对算法的了解并不是太多。了解的层次只是基于加密算法的一些应用上。也来浅谈一下加密算法在安全领域中的作用。写本篇文也是基于算法的应用和实现,也是我的基本原则,能用就行。

0x01 算法体制

在加密算法里面大致分为四大类:对称加密算法、非对称加密算法、散列函数、组合加密。

对称加密:指的是加密的密钥和解密的密钥相同。

非对称加密:指的是加密的密钥和加密的密钥不同。分为公钥和私钥。

散列函数:主要用于验证数据的完整性,长度不受限制,hash值容易计算,散列运算过程不可逆如:MD5、SHA

0x02 散列算法

Hash,一般翻译做散列、杂凑,或音译为哈希,是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

MD5

md5的运用范围也比较广,比如在一些数据库存储密码的时候会去使用到该算法去进行加密存储。当然也可以看到网上的一些md5破解的。但是他们都是基于彩虹表去跑,使用字典进行md5加密,然后把加密的值进行对比,从而判断该md5值的明文。

代码实例:

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5demo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");//设置要返回的摘要算法对象
        byte[] digest = md5.digest(name.getBytes()); //计算hash值
        System.out.println(HexBin.encode(digest));//输出hash结果
    }
}

Java安全之安全加密算法第1张

SHA

安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法。能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的算法。且若输入的消息不同,它们对应到不同字符串的机率很高。

SHA家族的五个算法,分别是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512

下面是一张对照图。

Java安全之安全加密算法第2张

代码实例:

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class jdksha1 {
    private static String name = "xiaoming";

    public static void main(String[] args) throws NoSuchAlgorithmException {
        MessageDigest sha = MessageDigest.getInstance("SHA");
        byte[] digest = sha.digest(name.getBytes());
        System.out.println(HexBin.encode(digest));

    }
}

Java安全之安全加密算法第3张

0x03 对称加密算法

对称加密算法,他的加解密密钥都是一样的。而对称加密的算法又分两大类,一种是每次对明文中的字节使用密钥进行加密,而第二种是对一组明文使用密钥进行加密。

Java安全之安全加密算法第4张

先来看看分组加密的工作模式。

分组加密的工作模式

1. ECB:电子密码本(最常用的,每次加密均产生独立的密文分组,并且对其他的密文分组不会产生影响,也就是相同的明文加密后产生相同的密文)
2. CBC:密文链接(常用的,明文加密前需要先和前面的密文进行异或运算,也就是相同的明文加密后产生不同的密文)
除了这两种常用的工作模式,还有:
3. CFB:密文反馈
4. OFB:输出反馈
5. CTR:计数器

分组密码填充方式

1. NoPadding:无填充
2. PKCS5Padding:
3. ISO10126Padding

常用的加密方式DES、3DES、AES。可以来对比一下,这几个算法的区别。

Java安全之安全加密算法第5张

BASE64

因为BASE64的加密解密算法是公开的,所以加密数据是没有任何安全性可言。先来看看API文档中提供的BASE64加密的类。除了在JDK中内置的也有一些第三方类会提供BASE64加密的类。

Java安全之安全加密算法第6张

Java安全之安全加密算法第7张

代码实例:

package com.demo;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.IOException;

public class base64demo {
    public static void main(String[] args) throws IOException {
        String name = "xiaoming";
        BASE64Encoder encoder = new BASE64Encoder//实例化BASE64Encoder对象
        String encode = encoder.encode(name.getBytes());//调用encode进行加密
        System.out.println(encode);
        BASE64Decoder base64Decoder = new BASE64Decoder();//实例化BASE64Decoder对象
        byte[] bytes = base64Decoder.decodeBuffer(encode);//进行解密
        System.out.println(bytes);
        String s = new String(bytes);
        System.out.println(s);


    }
}

Java安全之安全加密算法第8张

BASE64的加解密比较简单,在这里就不细说了。

DES

DES的算法其实已经被公开了,其实是不太安全的。

代码实例:

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

public class desdemo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {

        //1.生成密钥
        KeyGenerator des = KeyGenerator.getInstance("DES");//设置获取des的密钥
        des.init(56);//初始化密钥生成器,设置为56长度的密钥
        SecretKey secretKey = des.generateKey();//获取密钥
//        System.out.println(secretKey);
        byte[] deskey = secretKey.getEncoded(); //获取密钥的byte数组

        //2.密钥转换
        DESKeySpec desKeySpec = new DESKeySpec(deskey);
        SecretKeyFactory des1 = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey1 = des1.generateSecret(desKeySpec);
//        System.out.println(secretKey1);

        //3.加密
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");//选择算法、工作模式和填充方式
        cipher.init(Cipher.ENCRYPT_MODE,secretKey1);//选择加密模式和密钥进行加密
        byte[] res = cipher.doFinal(name.getBytes());//加密数据
//        System.out.println(res);
//        String s = new String(res);
        System.out.println(HexBin.encode(res));//输出加密后结果

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE,secretKey1);//选择密钥,并使用解密模式
        byte[] bytes = cipher.doFinal(res);//解密加密后的结果
        String s1 = new String(bytes);
        System.out.println(s1);

    }
}

Java安全之安全加密算法第9张

3DES

3DES也被叫做DESede,也就是基于DES三次加密。其实也有四层和两层DES,但是平时中用的最多的还是3DES。

Java安全之安全加密算法第10张

上面的图是他的一个算法的说明图。

其实3DES和DES在代码中的实现方式很相似。但是要注意的一点是密钥长度要选择正确,否则会报错。或者是可以使用SecureRandom()类,让他根据选择的加密算法使用默认的密钥长度。

Java安全之安全加密算法第11张

代码实例:

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import javax.crypto.*;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

public class jdk3des {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException {
//1.生成密钥
        KeyGenerator des = KeyGenerator.getInstance("DESede");//设置获取des的密钥
//        des.init(168);//初始化密钥生成器,设置为168长度的密钥
        des.init(new SecureRandom());//根据加密算法使用默认密钥长度
        SecretKey secretKey = des.generateKey();//获取密钥
//        System.out.println(secretKey);
        byte[] deskey = secretKey.getEncoded(); //获取密钥的byte数组

        //2.密钥转换
        DESedeKeySpec desKeySpec = new DESedeKeySpec(deskey);
        SecretKeyFactory des1 = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey1 = des1.generateSecret(desKeySpec);
//        System.out.println(secretKey1);

        //3.加密
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");//选择算法、工作模式和填充方式
        cipher.init(Cipher.ENCRYPT_MODE,secretKey1);//选择加密模式和密钥进行加密
        byte[] res = cipher.doFinal(name.getBytes());//加密数据
//        System.out.println(res);
//        String s = new String(res);
        System.out.println(HexBin.encode(res));//输出加密后结果

        //4.解密
        cipher.init(Cipher.DECRYPT_MODE,secretKey1);//选择密钥,并使用解密模式
        byte[] bytes = cipher.doFinal(res);//解密加密后的结果
        String s1 = new String(bytes);
        System.out.println(s1);

    }
}

AES

AES是目前用的最多的对称加密算法,一般用于移动通讯系统加密或者是基于SSH协议的软件

Java安全之安全加密算法第12张

AES的填充方式有三种:

(PKCS7Padding/PKCS5Padding/ZeroPadding)

PKCS7Padding跟PKCS5Padding的区别就在于数据填充方式,PKCS7Padding是缺几个字节就补几个字节的0,而PKCS5Padding是缺几个字节就补充几个字节的几,比如缺6个字节,就补充6个字节的6。

代码实例:

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import com.sun.xml.internal.messaging.saaj.util.Base64;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class aesdemo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        //1.获取密钥
        KeyGenerator aes = KeyGenerator.getInstance("AES");
        aes.init(128);
        SecretKey secretKey = aes.generateKey();
        byte[] encoded = secretKey.getEncoded();

        //2.密钥转换
        Key key = new SecretKeySpec(encoded, "AES");

        //3.加密
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE,key);
        byte[] bytes = cipher.doFinal(name.getBytes());
        System.out.println(new BASE64Encoder().encode(bytes));//加密完成后,再使用base64进行加密


        //4.解密
        cipher.init(Cipher.DECRYPT_MODE,key);
        byte[] bytes1 = cipher.doFinal(bytes);
        System.out.println(new String(bytes1));
        
    }
}

下面来放一张基于AES加解密的流程图。

Java安全之安全加密算法第13张

PBE

PBE算法(Password Based Encryption,基于口令加密)是一种基于口令的加密算法,其特点是使用口令代替了密钥,而口令由用户自己掌管,采用随机数杂凑多重加密等方法保证数据的安全性。PBE算法在加密过程中并不是直接使用口令来加密,而是加密的密钥由口令生成,这个功能由PBE算法中的KDF函数完成。KDF函数的实现过程为:将用户输入的口令首先通过“盐”(salt)的扰乱产生准密钥,再将准密钥经过散列函数多次迭代后生成最终加密密钥,密钥生成后,PBE算法再选用对称加密算法对数据进行加密,可以选择DES、3DES、RC5等对称加密算法

Java安全之安全加密算法第14张

以上这张图是PBE算法的实现方式

Java安全之安全加密算法第15张

代码实例:

package com.demo;

import com.sun.xml.internal.messaging.saaj.util.Base64;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;

public class pbedemo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, BadPaddingException, IllegalBlockSizeException {

        //1.初始化盐
        SecureRandom secureRandom = new SecureRandom();
        byte[] salt = secureRandom.generateSeed(8);

        //2. 获取密钥

        String password = "123456";
        PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
        Key key = factory.generateSecret(pbeKeySpec);
        //3.加密
        PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100);
        Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
        cipher.init(Cipher.ENCRYPT_MODE,key,pbeParameterSpec);
        byte[] bytes = cipher.doFinal(name.getBytes());
        System.out.println(new BASE64Encoder().encode(bytes));
        //4.解密

        cipher.init(Cipher.DECRYPT_MODE,key,pbeParameterSpec);
        byte[] res = cipher.doFinal(bytes);
        System.out.println(new String(res));

    }
}

Java安全之安全加密算法第16张

0x04 非对称加密算法

非对称加密算法需要两个密钥:公钥和私钥。公钥]与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

DH

1976年非对称加密算法思想被提出,但是当时并没有给出具体算法和方案,因为当时没有研究出单向函数(也就是信息摘要算法还没出现),但是IEEE的期刊中给出了通信时双方如何通过信息交换协商密钥的算法,也就是DH算法,通过该算法双方可以协商对称加密的密钥。

package com.demo;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import javax.crypto.*;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

public class dhdemo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException {
//        1.初始化发送方密钥
        KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH");
        sendKeyPairGenerator.initialize(512);
        KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair();
        byte[] sendPublicKeyEnc = sendKeyPair.getPublic().getEncoded();//生成发送方公钥,发送给接收方(网络、文件...)

//        2.初始化接收方密钥:
        KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(sendPublicKeyEnc);
        PublicKey receivePublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
        DHParameterSpec dhParameterSpec = ((DHPublicKey)receivePublicKey).getParams();
        KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
        receiverKeyPairGenerator.initialize(dhParameterSpec);
        KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
        PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
        byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();

//        3.构建接收方密钥:
        KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
        receiverKeyAgreement.init(receiverPrivateKey);
        receiverKeyAgreement.doPhase(receivePublicKey, true);

        SecretKey receiverDESKey = receiverKeyAgreement.generateSecret("DES");//接收方Key
//        4.构建发送方密钥:
        KeyFactory sendKeyFactory = KeyFactory.getInstance("DH");
        x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc);
        PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec);

        KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH");
        sendKeyAgreement.init(sendKeyPair.getPrivate());
        sendKeyAgreement.doPhase(sendPublicKey, true);

        SecretKey sendDESKey = sendKeyAgreement.generateSecret("DES");//发送方Key
//        5.发送方加密:
        Cipher sendCipher = Cipher.getInstance("DES");
        sendCipher.init(Cipher.ENCRYPT_MODE, sendDESKey);
        byte[] sendResult = sendCipher.doFinal(name.getBytes());
        System.out.println("sendResult :"+ HexBin.encode(sendResult));

//        6.接收方解密:
        Cipher receiverCipher = Cipher.getInstance("DES");
        receiverCipher.init(Cipher.DECRYPT_MODE, receiverDESKey);
        byte[] receiverResult = receiverCipher.doFinal(sendResult);
        System.out.println("receiverResult : "+new String (receiverResult));



    }
}

RSA

RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。RSA算法实现了公钥加密、私钥解密 和私钥解密、公钥加密的一个机制。

也就是说使用公钥来进行加密,想要解密获取明文内容,就必须使用对应的私钥来进行解密。而在其中私钥中的内容其实是比较长的,而公钥里面的内容会偏短一些。因为私钥一般会储存在本地,而公钥会放到各大互联网上,公钥比私钥内容短也是为了方便传输和存储。

代码示例:

package com.demo;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
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;

public class rsademo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
//        1.初始化密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//设置获取RSA的密钥
        keyPairGenerator.initialize(512);//设置密钥长度
        KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
        RSAPublicKey rsaPublic =(RSAPublicKey) keyPair.getPublic();//获取公钥
        RSAPrivateKey rsaPrivate = (RSAPrivateKey)keyPair.getPrivate();//获取私钥
//        System.out.println(new BASE64Encoder().encode(rsaPublic.getEncoded()));//输出公钥
        System.out.println("");
//        System.out.println(new BASE64Encoder().encode(rsaPrivate.getEncoded()));//输出私钥
//        2.私钥加密、公钥解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());//对密钥进行编码处理
        KeyFactory rsa = KeyFactory.getInstance("RSA");//设置获取RSA的密钥
        PrivateKey privateKey = rsa.generatePrivate(pkcs8EncodedKeySpec);//从提供的密钥规范生成私钥对象。
//        2.1私钥加密
        Cipher encodecipher = Cipher.getInstance("RSA");//设置获取RSA的密钥
        encodecipher.init(Cipher.ENCRYPT_MODE,privateKey);//设置为加密类型并传入私钥进行加密
        byte[] res = encodecipher.doFinal(name.getBytes());//对内容进行加密


        System.out.println(new BASE64Encoder().encode(res));

//        2.2公钥解密

        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublic.getEncoded());//对公钥进行编码处理
        rsa = KeyFactory.getInstance("RSA");//设置获取RSA的密钥
        PublicKey publicKey = rsa.generatePublic(x509EncodedKeySpec);//从提供的密钥规范生成公钥对象。 
        Cipher decodecipher = Cipher.getInstance("RSA");//设置获取RSA的密钥
        decodecipher.init(Cipher.DECRYPT_MODE,publicKey);//设置解密类型并传入公钥进行解密
        byte[] decoderes = decodecipher.doFinal(res);//对内容进行解密
        System.out.println(new String(decoderes));



    }
}


Java安全之安全加密算法第17张

下面再来看个公钥加密私钥解密的代码

package com.demo;

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
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;

public class rsademo {
    private static String name = "xiaoming";
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
//        1.初始化密钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//设置获取RSA的密钥
        keyPairGenerator.initialize(512);//设置密钥长度
        KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对
        RSAPublicKey rsaPublic =(RSAPublicKey) keyPair.getPublic();//获取公钥
        RSAPrivateKey rsaPrivate = (RSAPrivateKey)keyPair.getPrivate();//获取私钥
//        System.out.println(new BASE64Encoder().encode(rsaPublic.getEncoded()));//输出公钥
        System.out.println("");


//        3.公钥加密、私钥解密
        //        3.1公钥加密
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublic.getEncoded());
        KeyFactory encodersa = KeyFactory.getInstance("RSA");
        PublicKey publicKey = encodersa.generatePublic(x509EncodedKeySpec);
        Cipher encodecipher = Cipher.getInstance("RSA");
        encodecipher.init(Cipher.ENCRYPT_MODE,publicKey);
        byte[] encoderes = encodecipher.doFinal(name.getBytes());
        System.out.println(new BASE64Encoder().encode(encoderes));
//        3.2私钥解密
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());
        KeyFactory decodersa = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = decodersa.generatePrivate(pkcs8EncodedKeySpec);
        Cipher decodecipher = Cipher.getInstance("RSA");
        decodecipher.init(Cipher.DECRYPT_MODE,privateKey);
        byte[] decoderes = decodecipher.doFinal(encoderes);
        System.out.println(new String(decoderes));


    }
}

在代码中其实可以看到用到了x509EncodedKeySpecpkcs8EncodedKeySpec的类,其实这两个类一个用于对私钥进行编码的,一个是对私钥进行编码。

0x05 结尾

在安全中其实加密算法显得格外的重要,举个例子,比如说冰蝎,为什么就能过一些设备呢?其实分析过冰蝎的,或者是看过冰蝎作者大大的文章的应该会知道,冰蝎在流量传输中也是做了加密的。使用的是AES加密。首先是将客户端发送的命令转换成字节码,然后使用aes进行加密,然后在客户端也就是webshell获取密钥进行解密得到字节码,最后就是使用defineClass来动态加载字节码进行执行。

但是在后面各大厂商的设备随着各大厂商设备的不断升级,冰蝎2还是被杀了。这是因为在冰蝎aes传输密钥的时候被识别出来了。那么我们如果再对该密钥进行更狠一点加密呢?虽然说也能实现,步骤繁琐一些。但是这还是会产生一些流量。在冰蝎3中的做法是去除了握手的过程,直接写死在Webshell中的字符串作为AES密钥解密流量包。

后面打算基于冰蝎进行一个重写,并使用不同的算法来实现加密。

免责声明:文章转载自《Java安全之安全加密算法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇oracle 跟踪文件和转储命令jdk线程的简单使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

动态修改log4j.properties配置文件,无需重启就可以生效

1.log4j.properties自带有一个PropertyConfigurator的类,通过方法configureAndWatch实现 代码实现 import lombok.extern.slf4j.Slf4j; import org.apache.log4j.PropertyConfigurator; import java.io.FileInpu...

ElasticSearch 问题分析:No data nodes with HTTP-enabled available

环境:ES-5.4.0版本,部署方式:3master node+2client node+3data node 说明:data node和client node都配置了http.enabled: false,程序在写数据时报错:No data nodes with HTTP-enabled available 源码分析: 1 public static...

WebBench简介

一:简介:          Webbench是一个在linux下使用的非常简单的网站压测工具。它使用fork()模拟多个客户端同时访问设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力。Webbench使用C语言编写, 代码加起来不到600行。          http://home.tiscali.cz/~cz2...

SQLServer 的存储过程与java交互

一、   存储过程简介 Sql Server的存储过程是一个被命名的存储在服务器上的Transacation-Sql语句集合,是封装重复性工作的一种方法,它支持用户声明的变量、条件执行和其他强大的编程功能。 存储过程相对于其他的数据库访问方法有以下的优点:    (1)重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。     (2)...

c++设计模式:命令模式(Command Pattern)

定义: 命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象,命令模式也支持可撤销的操作。命令模式可将“动作的请求者”从“动作的执行者”对象中解耦。 场景: 我们要设计一个遥控器,可以通过按动上边的控制按钮控制卧室和厨房的灯,还能控制卧室中的音响的开关。遥控器及时我们的“动作的请求者”,而灯和音响就是我们的“动作的执行者”。当我们...

【原创】Kafka接受发送消息对象Object基础版

首先感谢 kafka 中国社区 王扬庭例子的帮助和指导~~~~~(kafka_2.9.2-0.8.1.1) kafka常用的发送消息的方法如下: Properties props = new Properties(); props.put("zookeeper.connect", "slaves2:2181,slaves3:2181,slaves4:218...