Java——基於JDK的幾種加密方式
阿新 • • 發佈:2019-02-20
主要包括base64,AES,RSA,SHA和MD5等加密方式
未使用任何第三方工具,直接執行main方法即可
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class TestSecu {
public static void main(String[] args) {
try {
//base64();
//aes();
//sm();
rsa();
//sing();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* RSA加密
* 非對稱加密,加密金鑰分為公鑰和私鑰。可以使用公鑰加密私鑰解密,也可以使用私鑰加密公鑰解密
* 數字簽名是帶有金鑰(公鑰、私鑰)的訊息摘要演算法。主要作用是驗證資料的完整性、認證資料來源、抗否認。在數字簽名的實現中我們使用私鑰簽名、公鑰驗證。常用的數字簽名演算法包括RSA、DSA、ECDSA。
*/
static void rsa() throws Exception {
String src = "hello rsa";
//1.初始化金鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);//金鑰長度為64的整數倍,最大是65536
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
byte[] pk = rsaPublicKey.getEncoded();
byte[] sk = rsaPrivateKey.getEncoded();
System.out.println("RSA公鑰:" + parseByte2HexStr(pk));
System.out.println("RSA私鑰:" + parseByte2HexStr(sk));//可以將其儲存到本地檔案中
//2.1私鑰加密,公鑰解密【加密】
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("RSA私鑰加密:" + parseByte2HexStr(result));
//2.2私鑰加密,公鑰解密【解密】
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(result);
System.out.println("RSA公鑰解密:" + new String(result));
//3.1公鑰加密,私鑰解密【加密】
x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(src.getBytes());
System.out.println("RSA公鑰加密:" + parseByte2HexStr(result));
//3.2公約加密,私鑰解密【解密】
pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
System.out.println("RSA私鑰解密:" + new String(result));
}
/**
* 數字簽名-rsa
* 數字簽名是帶有金鑰(公鑰、私鑰)的訊息摘要演算法。主要作用是驗證資料的完整性、認證資料來源、抗否認。在數字簽名的實現中我們使用私鑰簽名、公鑰驗證。常用的數字簽名演算法包括RSA、DSA、ECDSA。n
*/
static void sing() throws Exception {
String src = "hello rsa";
//1.初始化金鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
//2.執行數字簽名【私鑰簽名】
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Signature signature = Signature.getInstance("MD5WithRSA");
signature.initSign(privateKey);
signature.update(src.getBytes());
byte[] result = signature.sign();
System.out.println("RSA簽名:" + parseByte2HexStr(result));
//3.驗證簽名【公鑰驗證】
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5WithRSA");
signature.initVerify(publicKey);
signature.update(src.getBytes());
boolean bool = signature.verify(result);
System.out.println("數字簽名是否有效?" + bool);
}
/**
* Base64
* Base64並不是一種加密/解密演算法,而是一種編碼方式。Base64不生成金鑰,通過Base64編碼後的密文就可以直接“翻譯”為明文,但是可以通過嚮明文中新增混淆字元來達到加密的效果。
* 注意,都是基於位元組的
*/
static void base64() throws IOException {
String src = "www.xxx.com?title=你好";
//加密
BASE64Encoder encoder = new BASE64Encoder();
String encode = encoder.encode(src.getBytes());
System.out.println("加密後:"+encode);
//解密
BASE64Decoder decoder = new BASE64Decoder();
byte[] decode = decoder.decodeBuffer(encode);
System.out.println("解密後:"+new String(decode));
}
/**
* AES
* AES是現在對稱加密演算法中最流行的演算法之一。加密金鑰和解密金鑰相同,加密運算和解密運算互為逆運算。是一種初等的加密演算法。主要的演算法有DES(3DES)、AES、PBE、IDEA。
*/
static void aes() throws Exception {
String src = "name=張三";//加密內容
String pkey = "123";//祕鑰
//配置--加密與解密公用的
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128, new SecureRandom(pkey.getBytes()));
SecretKey secretKey = kgen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
Cipher cipher = Cipher.getInstance("AES");// 建立密碼器
//加密
byte[] byteContent = src.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化加密器
byte[] result = cipher.doFinal(byteContent);
String p = parseByte2HexStr(result);//不可直接轉成字串
System.out.println("密文:" + p);
//解密
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化解密器
byte[] decryptFrom = parseHexStr2Byte(p);
byte[] result1 = cipher.doFinal(decryptFrom);
System.out.println("原文:" + new String(result1));
}
/**
* SHA與MD5
* 不可逆的加密方式,是為了防止訊息在傳輸過程中的篡改。驗證資訊等。
*/
static void sm() throws Exception {
String src = "abcd";
//加密
MessageDigest messageDigest = MessageDigest.getInstance("MD5");// 構建加密型別/SHA-512
messageDigest.update(src.getBytes());// 傳入要加密的字串
byte[] b = messageDigest.digest();
String p = parseByte2HexStr(b);
System.out.println("加密後"+p);
}
/**
* 二進位制轉換成16進位制,加密後的位元組陣列不能直接轉換為字串
*/
static 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進位制轉換成二進位制
*/
static 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;
}
}