加密算法Java

1、加密算法的分类

对称加密算法:使用一个密钥,即可加密,也可解密。

非对称加密算法:使用一对密钥,公钥只能加密不能解密,只有私钥可以用来解密。运算速度不及对称加密算法。

常见的加密算法:

算法名分类是否幂等目前是否破解破解年限
RSA-155(512bit)非对称加密已被破解1999年耗费5个月
RSA-786(786bit)非对称加密已被破解2009年
RSA-1024(1024bit)非对称加密未被破解预计这几年
RSA-2048(2048bit)非对称加密未被破解
RSA系列非对称加密量子计算机
DES对称加密已被破解1990年短时间内
AES对称加密未被破解

2、RSA 算法演示

需要选择两个质数:5 和 11

计算 n : 5 * 11 = 55

n = 11, 0111 因此 这个密钥是 6 bit

计算 φ(n) = (5 - 1) * (11 - 1) = 40

选择一个数 e 当作公钥因子,需要满足 1 < e < φ(n), 并且 e 和 φ(n) 互质:e = 13

得到公钥 :(n = 35, e = 13)

计算私钥因子 d,需要满足 (e * d) mod φ(n) = 1。计算得出 d = 37

得到私钥:(n = 55, d = 37)

加密公式:f(x) = (x ^ e) mod n

解密公式:f(x) = (x ^ d) mod n

对 20 进行加密,结果为:(20 ^ 13) mod 55 = 25

对 25 进行解密,结果为:(25 ^ 37) mod 55 = 20

public static void main(String[] args) {
		rsa(20, 55, 13); // 加密, 25
		rsa(25, 55, 37); // 解密, 20
	}
	
	/**
	 * 
	 * @param x 待加密或解密的值
	 * @param n 
	 * @param e 密钥因子
	 */
	public static void rsa(int x, int n, int e) {
		int sum = x;
		for (int i = 1; i < e; i++) {
			sum = sum * x;
			if (sum > n)
				sum = sum % n;
		}
		System.out.println(sum);
	}

3、使用工具生成 RSA 密钥

使用 openSSL 工具生成私钥

openssl genrsa -out rsa_pri.key 1024

使用 openssl 根据私钥生成公钥

openssl rsa -in rsa_pri.key -pubout -out rsa_pub.key

生成的私钥编码为 pkcs12, Java 不能直接使用,需要转成 pkcs8 格式

openssl pkcs8 -topk8 -inform PEM -in rsa_pri.key -outform PEM -nocrypt
4、Java加解密
package zh.utils;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;



public class RSA {
	

	public static void main(String[] args) throws Exception {
		String priKeyStr = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBANg9tNBlqb0rIAKXzkFOZ8+Uk3qOLaqXpqBSeiV/YOiAlWe5lI7U7RAiV/vHabsm0jRWz+UdsSgMOfUaJmAjAMvdqPEua3mJo5rGNkeBqop42bj0XLGDcyd562HwV1yaZDGQrAREqLrsDIcSc3R9ULl+9R/m9MFpwK6mr5IkG6xBAgMBAAECgYEAl+kBlUVWMSaSnj+3Dfnew91Endw0CJvw2sAWPzF1CuEKFIwy6QR8ZdE6rg4xIODs2wgBlJt/UPsF3EI6o17ztviac/pCvu09au1eW1f2aHGRvLSHTVVpA6V7FcZvZsk0J+3dGWhv0VxnVrUGW2r/BBwouxoe4R3ZL/Mvi3YxM2ECQQD/UHrgAa9wATMiuBcmcPTZSDHjr9DbddTs9XmHpAGYSrODLpWBHfYX8yGMGQfEpaJFIRccScankF+OoRsfhDYvAkEA2NJdXpy3SKxePLrcHWI9XnpFxg4QDIfK11fiy7DspHJGNxkgnuz6OqxZ71l88z0tlU2Q8D6793dzGdaw0GMYjwJBANs8bIb2a4OuRA7ILXjg/h+mktCFJL+Oyyw/DgCfoI75dnRrCA47gBrIuEHpLHZ8FH9wDrxHzcINg0Cirvu9OBkCQGZUEgDfEZlY0Dj1L4EmpjP6nQd2B5kCVXcAYWcknuqVjBHg6AZZbVdXlDJkF5ZsnyDBtM/Nq8SFOWtOabBPtH0CQQCzVp0/Awzo7CYYXnQcK6qro8x9eDSB1eZ0DVuth36xh2CC2OKi2gjMiQBrs2se3W/TUaTiW546rCwTDTvSHqjs";
		String pubKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYPbTQZam9KyACl85BTmfPlJN6ji2ql6agUnolf2DogJVnuZSO1O0QIlf7x2m7JtI0Vs/lHbEoDDn1GiZgIwDL3ajxLmt5iaOaxjZHgaqKeNm49Fyxg3Mneeth8FdcmmQxkKwERKi67AyHEnN0fVC5fvUf5vTBacCupq+SJBusQQIDAQAB";
		String data = "this is rsa";
		// 加载公钥
		RSAPublicKey pubKey = loadPublicKey(pubKeyStr);
		// 加载私钥
		PrivateKey priKey = loadPrivateKey(priKeyStr);
		
		// 使用公钥加密
		String sign = sign(pubKey, data);
		System.out.println("加密结果为:" + sign);
		
		String decrypt = decrypt(priKey, sign);
		System.out.println("解密结果为:" + decrypt);
	}
	
    /**
     * 公钥加密过程
     *
     */
    public static String sign(RSAPublicKey publicKey, String data)
            throws Exception {
    	Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] output = cipher.doFinal(data.getBytes());
        return Base64ByteToString(output);
    }
    
    //私钥解密
  	public static String decrypt(PrivateKey privateKey, String data) throws Exception{
  		Cipher cipher = Cipher.getInstance("RSA");
  		cipher.init(Cipher.DECRYPT_MODE, privateKey);
  		byte[] bytes = cipher.doFinal(StringToBase64Byte(data));
  		return new String(bytes);
  	}

  	/**
     * 从字符串中加载私钥
     */
  	public static PrivateKey loadPrivateKey(String priStr) throws Exception{
		byte[] keyBytes = StringToBase64Byte(priStr);
		PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
		return privateKey;
	}


    /**
     * 从字符串中加载公钥
     */
    public static RSAPublicKey loadPublicKey(String publicKeyStr)
            throws Exception {
    	byte[] buffer = StringToBase64Byte(publicKeyStr);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
        return (RSAPublicKey) keyFactory.generatePublic(keySpec);
    }
    

    /**
     * 将byte[] 转换成字符串
     */
    public static String byte2Hex(byte[] srcBytes) {
        StringBuilder hexRetSB = new StringBuilder();
        for (byte b : srcBytes) {
            String hexString = Integer.toHexString(0x00ff & b);
            hexRetSB.append(hexString.length() == 1 ? 0 : "").append(hexString);
        }
        return hexRetSB.toString();
    }


    /**
     * 将字符串转为 Base64 格式的 byte
     */
    public static byte[] StringToBase64Byte(String str) {
    	return Base64.getDecoder().decode(str);
    }
    
    /**
     * 将 Base64 格式的 byte 转为字符串
     */
    public static String Base64ByteToString(byte[] bt) {
    	return Base64.getEncoder().encodeToString(bt);
    }
    
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值