标签:byte ice javadoc 非对称加密 blocks integer auth 执行 版本
/**
*对字符简单的加密
*/
public class SimpleEncryptionDemo01 {
public static void main(String[] args) {
// 确定加密的内容
String content = "i love you tonight 404 see you z";
//加密
String encryptData = encrypt(content);
System.out.println("加密后:" + encryptData);
//解密
String decryptData = decrypt(encryptData);
System.out.println("解密后:" + decryptData);
}
/**
* 加密方法
*
* @param content
* @return
*/
public static String encrypt(String content) {
// 将内容转换成字符数组
char[] charArray = content.toCharArray();
// 遍历出所有字符
for (int i = 0; i < charArray.length; i++) {
// 对所有字符进行 + 1操作
charArray[i] = (char) (charArray[i] + 1);
}
return new String(charArray);
}
/**
* 解密方法
*
* @param encryptData
* @return
*/
public static String decrypt(String encryptData) {
// 将内容转换成字符数组
char[] charArray = encryptData.toCharArray();
System.out.println(new String(charArray));
// 解密
for (int i = 0; i < charArray.length; i++) {
charArray[i] = (char) (charArray[i] - 1);
}
return new String(charArray);
}
}
字节和字符的区别?
* UTF-8编码下,一个英文或数字字符就是一个字节
* UTF-8编码下,一个汉字代表三个字节。
* 为什么new String(bytes)的时候回发生乱码,就是因为加密后得到的字节找不到对应的字符。
* Base64的原理
/**
*对字节进行加密
*/
public class SimpleEncryptionDemo2 {
public static void main(String[] args) {
// 测试字节字符
String content = "中文";
int key = 80;
String encryptData = encrypt(content,key);
System.out.println("+密后:" + encryptData);
String decryptData = decrypt(encryptData,key);
System.out.println("解密后:" + decryptData);
}
/**
* 加密
*
* @param content
* @return
*/
public static String encrypt(String content,int key) {
// 第一步,转换成字节数组
byte[] bytes = content.getBytes();
System.out.println("打印未加密的字节数组:");
Util.printBytes(bytes);
System.out.println("_________________________________________");
// 第二步,遍历出所有字节,并做+1处理
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) (bytes[i] + key);
}
System.out.println("打印加密的字节数组:");
Util.printBytes(bytes);
System.out.println("_________________________________________");
// return new String(bytes);
return Base64.getEncoder().encodeToString(bytes);
}
/**
* 解密
* @param encryptData
* @return
*/
public static String decrypt(String encryptData,int key) {
// 第一步,转换成字节数组,加密时使用Base64编码,那解密时也要使用Base64解码
byte[] bytes = Base64.getDecoder().decode(encryptData);
// byte[] bytes = encryptData.getBytes();
System.out.println("打印经过两次转换后的字节数组:");
Util.printBytes(bytes);
System.out.println("_________________________________________");
// 解密
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) (bytes[i] - key);
}
System.out.println("打印解密后的字节数组:");
Util.printBytes(bytes);
System.out.println("_________________________________________");
return new String(bytes);
}
}
常见算法:AES、DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK
AES:高级加密标准(Advanced Encryption Standard)
DES:数据加密标准(Data Encryption Standard)
public class SymmetricalEncryptionDemo01 {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
// 声明要加密的内容
String content = "今晚404,不见不散";
//生成key
SecretKey key = createKey();
//加密
String encryptData = encrypt(content, key);
System.out.println(encryptData);
//解密
String decryptData = decrypt(encryptData, key);
System.out.println(decryptData);
}
/**
* 生成key
* @return
* @throws NoSuchAlgorithmException
*/
public static SecretKey createKey() throws NoSuchAlgorithmException {
// 生成key
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecretKey secretKey = keyGenerator.generateKey();
return secretKey;
}
/**
* 加密方法
*
* @param content
* @return
* @throws InvalidKeyException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static String encrypt(String content, SecretKey key) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// 获取cipher单例对象
Cipher cipher = Cipher.getInstance("AES");
// 初始化cipher,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
// 开始加密
byte[] encryptBytes = cipher.doFinal(content.getBytes());
return Base64.getEncoder().encodeToString(encryptBytes);
}
/**
* @param encryptData
* @return
*/
public static String decrypt(String encryptData, SecretKey key) throws InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
byte[] encryptBytes = Base64.getDecoder().decode(encryptData);
// 获取cipher单例对象
Cipher cipher = Cipher.getInstance("AES");
// 解密
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
}
将生成的key保存到本地,然后解密时和下一次加密时就只需要到本地读取即可。。
/**
*保存key到本地
*/
public class SymmetricalEncryptionDemo02 {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException, IOException, ClassNotFoundException {
// 声明要加密的内容
String content = "今晚404,不见不散";
//第一次生成key,并序列化到本地
// SecretKey key = createKey();
// SerializableUtil.saveObject2File("heima.key", key);
//从文件中读取key
SecretKey key = (SecretKey) SerializableUtil.readObjectFromFile("heima.key");
System.out.println(key);
//加密
String encryptData = encrypt(content, key);
System.out.println(encryptData);
//解密
String decryptData = decrypt(encryptData, key);
System.out.println(decryptData);
}
/**
* 生成key
* @return
* @throws NoSuchAlgorithmException
*/
public static SecretKey createKey() throws NoSuchAlgorithmException {
// 生成key
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecretKey secretKey = keyGenerator.generateKey();
return secretKey;
}
/**
* 加密方法
*
* @param content
* @return
* @throws InvalidKeyException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static String encrypt(String content, SecretKey key) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// 获取cipher单例对象
Cipher cipher = Cipher.getInstance("AES");
// 初始化cipher,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
// 开始加密
byte[] encryptBytes = cipher.doFinal(content.getBytes());
return Base64.getEncoder().encodeToString(encryptBytes);
}
/**
* @param encryptData
* @return
*/
public static String decrypt(String encryptData, SecretKey key) throws InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
byte[] encryptBytes = Base64.getDecoder().decode(encryptData);
// 获取cipher单例对象
Cipher cipher = Cipher.getInstance("AES");
// 解密
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
}
/**
* 生成key
* @return
* @throws NoSuchAlgorithmException
*/
public static SecretKey createKey(String keyword) throws NoSuchAlgorithmException {
// 生成key
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(new SecureRandom(keyword.getBytes()));
SecretKey secretKey = keyGenerator.generateKey();
return secretKey;
}
常见算法:RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等
应用场景:银行和电商网站,他就采用非对称加密,将公钥给所有人,你们就用这个公钥加密,私钥我自己留着,谁也不知道,所以除了我,谁也解密不了。
(数据量不大的情况下可用,加密数据小于117个字节,解密数据小于128个字节)
public class AysmmetricEncryptionDemo {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
String content = "今晚小树林,等你哦";
//生成密钥对
KeyPair keyPair = createKeyypair();
//获取公钥私钥
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
//加密
String encryptData = encrypt(content, publicKey);
System.out.println("加密后:" + encryptData);
//解密
String decryptData = decrypt(encryptData, privateKey);
System.out.println("解密后:" + decryptData);
}
/**
* 生成秘钥对
* @return
* @throws NoSuchAlgorithmException
*/
public static KeyPair createKeyypair() throws NoSuchAlgorithmException{
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
/**
* 加密
*
* @param content
* @return
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws InvalidKeyException
*/
public static String encrypt(String content, PublicKey publicKey) throws NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
// 获取cipher对象
Cipher cipher = Cipher.getInstance("RSA");
// 初始化cipher,指定模式为加密,传入公钥
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptBytes = cipher.doFinal(content.getBytes());
return Base64.getEncoder().encodeToString(encryptBytes);
}
/**
* 解密方法
*
* @param encryptData
* @param privateKey
* @return
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws Exception
*/
public static String decrypt(String encryptData, PrivateKey privateKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
byte[] encryptBytes = Base64.getDecoder().decode(encryptData);
// 获取cipher对象
Cipher cipher = Cipher.getInstance("RSA");
// 小芝解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
}
/**
* 处理大量数据时,分块加密/解密
* @param content
* @param cipher
* @param max
* @return
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws IOException
*/
private static byte[] doFinalWithBlock(byte[] bytes, Cipher cipher,int max)
throws IllegalBlockSizeException, BadPaddingException, IOException {
int len = bytes.length;//3000
//加密数据长度不能超过117个byte
int inputOffset = 0;//2700
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while (len > inputOffset) {
//特殊情况,最后一次剩下的数据不足117
if ((len - inputOffset) >= max) {
byte[] encryptBytes = cipher.doFinal(bytes, inputOffset, max);
baos.write(encryptBytes);
inputOffset += max;
}else {
byte[] encryptBytes = cipher.doFinal(bytes, inputOffset, len - inputOffset);
baos.write(encryptBytes);
inputOffset = len;
}
}
byte[] byteArray = baos.toByteArray();
return byteArray;
}
消息摘要是一个不可逆的过程。常用来防篡改。
常见算法:MD5、SHA、CRC等
/**
* byte数组转16进制字符串
* @param bytes
* @return
*/
public static String bytes2Hex(byte[] bytes){
StringBuffer sBuffer = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
//取高位
int high = (bytes[i] & 0xf0) >> 4;
//取低位
int low = bytes[i] & 0x0f;
sBuffer.append(HEXSTR[high]).append(HEXSTR[low]);
}
return sBuffer.toString();
}
/**
* 16进制字符串转字节数组
* @param hex
* @return
*/
public static byte[] hex2Bytes(String hex){
int len = hex.length()/2;
//声明一个字节数组用于接收转换后的字节
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++) {
//首先取高位,取偶数位
String highStr = hex.substring(2 * i, 2 * i + 1);
String lowStr = hex.substring(2 * i + 1, 2 * i + 2);
int high = Integer.parseInt(highStr, 16) << 4;
int low = Integer.parseInt(lowStr, 16);
bytes[i] = (byte) (high + low);
}
return bytes;
}
public class DigitalSignatureDemo {
public static void main(String[] args) throws Exception {
String content = "今晚六点半,不见不散!!!";
byte[] bytes = content.getBytes();
//获取数字签名的单例对象
Signature signature = Signature.getInstance("MD5withRSA");
//从文件中读取私钥
PrivateKey privateKey = (PrivateKey) SerializableUtil.readObjectFromFile("heima.privateKey");
//私钥跟公钥不是一对,那么认证失败!
// KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance("RSA");
/ KeyPair keyPair = pairGenerator.generateKeyPair();
// PrivateKey privateKey = keyPair.getPrivate();
//初始化签名
signature.initSign(privateKey);
//加载内容
signature.update(bytes);
//进行签名
byte[] signBytes = signature.sign();//得到签名后的byte数组,就相当于私钥加密后的MD5值
//获取公钥
PublicKey publicKey = (PublicKey) SerializableUtil.readObjectFromFile("heima.publicKey");
//认证流程
//初始化认证
signature.initVerify(publicKey);
// String content2 = "今晚八点,606嘿嘿嘿!";
//加载内容
signature.update(bytes);
//认证
boolean verify = signature.verify(signBytes);//认证加密后的MD5值
System.out.println(verify);
}
}
获取文件中的证书
// 获取证书工厂的实例
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream inStream = new FileInputStream(new File("heima.cer"));
X509Certificate certificate = (X509Certificate) cf.generateCertificate(inStream);
单向/双向认证的原理
为了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议。SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术。SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证,其主要过程如下:
① 浏览器发送一个连接请求给安全服务器。
② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器。
③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的 CA 中心所签发的。如果是,就继续执行协议;如果不是,客户浏览器就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。
④ 接着客户浏览器比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果是一致的,客户浏览器认可这个服务器的合法身份。
⑤ 服务器要求客户发送客户自己的证书。收到后,服务器验证客户的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得用户的公钥。
⑥ 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。
⑦ 服务器从客户发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户的公钥加过密后通知浏览器。
⑧ 浏览器针对这个密码方案,选择一个通话密钥,接着用服务器的公钥加过密后发送给服务器。
⑨ 服务器接收到浏览器送过来的消息,用自己的私钥解密,获得通话密钥。
⑩ 服务器、浏览器接下来的通讯都是用对称密码方案,对称密钥是加过密的。
代码访问
public class HttpsDemo {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException {
//第一种方式,我所有的证书都不检查
SSLContext sslContext = SSLContext.getInstance("TLS");//TLS 是transport Layer safe
//获取信任管理者工厂
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
//获取keyStore
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null);
//从文件中读取证书
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream inStream = new FileInputStream(new File("srca.cer"));
X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
//给keyStore设置证书
ks.setCertificateEntry("12306", cert);
trustManagerFactory.init(ks);
TrustManager[] tm = trustManagerFactory.getTrustManagers();
sslContext.init(null, tm, null);
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
// TODO Auto-generated method stub
URL url = new URL("https://kyfw.12306.cn/otn/");
//第二步,获取coon
HttpsURLConnection coon = (HttpsURLConnection) url.openConnection();
InputStream inputStream = coon.getInputStream();
String response = Util.inputStream2String(inputStream);
System.out.println(response);
}
}
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="证书的全路径名称" keystorePass="证书的密码"/>
keytool -genkeypair -alias "itheima" -keyalg "RSA" -keystore "haha.keystore"
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 把他注释掉。
标签:byte ice javadoc 非对称加密 blocks integer auth 执行 版本
原文地址:http://blog.csdn.net/shuaicihai/article/details/70502541