Java安全(一)

1 加密/解密
1.1 实现细节
 f     加密算法
 密钥(k)         加密钥匙  
 明文(m)        加密前的明文信息  
 密文(c)         被加密后的密文信息 
                    m-----f(key)----->c-----f(key)----->m    
   
1.1.1 加密/解密算法
JDK有一个Cipher类,该类是所有密码算法的超类。
Cipher cipher = Cipher.getInstance(algName);
或Cipher cipher = Cipher.getInstance(algName, pName);
algName: 加密算法
pName: 加密算法提供商
一旦获得一个密码对象,就可以通过设置模式和密钥来对他初始化。
cipher.init(mode,key);
模式主要分以下几种:
Cipher.ENCRYPT_MODE      加密
Cipher.DECRYPT_MODE      解密
Cipher.WRAP_MODE            将一个Key封装成字节
Cipher.UNWRAP_MODE      将前述已封装的key还原为Key对象

public byte[] doFinal(byte[] input);
对input数据进行加密,返回加密后的密文。


1.1.2 密钥
密钥可以有两个方法获得,一个是生成一个完全随机的密钥。另外一个方法就是使用口令产生一个密码。
 产生一个随机密钥:
KeyGenerator keyGenerator = KeyGenerator.getInstance(algName);
SecureRandom secureRandom = new SecureRandom();
keyGenerator.init(secureRandom);
key = keyGenerator.generateKey();
 产生口令产生密钥:
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(algName) ; 
DESKeySpec desKeySpec = new DESKeySpec(createKey);
createKey: 口令字节数组,使用 createKey中的前 8 个字节作为 DES 密钥的密钥内容,如果createKey长度不够8个字节,则抛出InvalidKeyException异常。
key = secretKeyFactory.generateSecret(desKeySpec) ;
 产生公钥私钥:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algName);
SecureRandom random = new SecureRandom();
keyPairGenerator.initialize(SIZE, random);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
privateKey = keyPair.getPrivate();
publicKey = keyPair.getPublic();
 加密密钥:
cipher = Cipher.getInstance(algName);
cipher.init(Cipher.UNWRAP_MODE , key);
key : 公钥
cipher.wrap(key);
key : 被加密的密钥
 解密密钥:
cipher = Cipher.getInstance(algName);
cipher.init(Cipher.UNWRAP_MODE,key);
key : 私钥
cipher.unwrap(key, algName,Cipher.SECRET_KEY);
key : 字节数组,加密后的密钥


1.2 代码示例
对称密码是加密和解密都使用相同的密钥。
1.2.1 对称密码
1.2.1.1 随机产生密码
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

public class RegularCipher {

 private Key key = null ;
 private Cipher cipher = null ;
 
 public static void main(String[] args) {
  RegularCipher regularCipher = new RegularCipher();
  String information = "欢迎大家批评";
  byte[] crypt_info = null;             // 加密后的密文
  byte[] not_crypt_info = null;      // 解密后的明文
  
  // 创建密钥
  regularCipher.CreateRandomRegularKey();
  System.out.println("要加密的信息:       " + information);
  
  // 生成加密算法
  regularCipher.createCipher(Cipher.ENCRYPT_MODE);
  crypt_info = regularCipher.Crypt(information.getBytes());
  System.out.println("加密后的密文:       " + new String(crypt_info));
  System.out.println();
  
  // 生成解密算法
  regularCipher.createCipher(Cipher.DECRYPT_MODE);
  not_crypt_info = regularCipher.Crypt(crypt_info);
  System.out.println("解密后的明文:       " + new String(not_crypt_info));
 }
 
 /**
  * 随机生成对称密钥
  */
 public void CreateRandomRegularKey(){
  try {
   KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
   SecureRandom secureRandom = new SecureRandom();
   keyGenerator.init(secureRandom);
   key = keyGenerator.generateKey();
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 创建加密/解密算法
  */
 public void createCipher(int mode) {
  try {
   cipher = Cipher.getInstance("DES");
   cipher.init(mode,key);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (NoSuchPaddingException e) {
   e.printStackTrace();
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 加密/解密
  */
 public byte[] Crypt(byte[] in){
  try {
   return cipher.doFinal(in); 
  } catch (IllegalBlockSizeException e) {
   e.printStackTrace();
  } catch (BadPaddingException e) {
   e.printStackTrace();
  }
  return null ;
 }
}
1.2.1.2 使用口令产生密码
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

public class RegularCipher {

 private Key key = null ;
 private Cipher cipher = null ;
 
 public static void main(String[] args) {
  RegularCipher regularCipher = new RegularCipher();
  String information = "阿里软件 AEP平台";
  byte[] createKey = "12345678".getBytes();
  byte[] crypt_info = null;             // 加密后的密文
  byte[] not_crypt_info = null;         // 解密后的明文
  
  System.out.println("要加密的信息:       " + information);
  // 创建密钥
  regularCipher.CreateMyRegularKey(createKey,"DES");
  // 生成加密算法
  regularCipher.createCipher(Cipher.ENCRYPT_MODE,"DES");
  crypt_info = regularCipher.Crypt(information.getBytes());
  System.out.println("加密后的密文:       " + new String(crypt_info));
  // 生成解密算法
  regularCipher.createCipher(Cipher.DECRYPT_MODE,"DES");
  not_crypt_info = regularCipher.Crypt(crypt_info);
  System.out.println("解密后的明文:       " + new String(not_crypt_info));
 }
 
 /**
  * 生成自指定密钥
  */
 public void CreateMyRegularKey(byte[] createKey,String alg){
  try {
   SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(alg) ;
   DESKeySpec desKeySpec;
   desKeySpec = new DESKeySpec(createKey);
   key = secretKeyFactory.generateSecret(desKeySpec) ;
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }  catch (InvalidKeySpecException e) {
   e.printStackTrace();
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 创建加密/解密算法
  */
 public void createCipher(int mode , String alg) {
  try {
   cipher = Cipher.getInstance(alg);
   cipher.init(mode,key);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (NoSuchPaddingException e) {
   e.printStackTrace();
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 加密/解密
  */
 public byte[] Crypt(byte[] in){
  try {
   return cipher.doFinal(in);
  } catch (IllegalBlockSizeException e) {
   e.printStackTrace();
  } catch (BadPaddingException e) {
   e.printStackTrace();
  }
  return null;
 }
}
1.2.2 公钥私钥加解密
对称密码有个弱点在是密码的分发。如果密钥修改了则必须有一个安全的通道重新分发新密钥,但不一定拥有一条安全的通道。我们用公钥私钥加解密技术来解决这个问题。
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class PairCipher {
 private PrivateKey privateKey = null ;
 private PublicKey publicKey = null ;
 private Cipher cipher = null ;
 private static int SIZE = 512 ;
 
 public static void main(String[] args) {
  PairCipher pairCipher = new PairCipher();
  String information = "欢迎大家批评";
  byte[] crypt_info = null;             // 加密后的密文
  byte[] not_crypt_info = null;      // 解密后的明文
  
  System.out.println("要加密的信息:       " + information);
  // 创建公钥和私钥
  pairCipher.createPublicAndPrivateKey("RSA");
  // 用公钥加密
  pairCipher.createCipher(Cipher.ENCRYPT_MODE,"RSA",pairCipher.getPublicKey());
  crypt_info = pairCipher.Crypt(information.getBytes());
  System.out.println("加密后的密文:       " + new String(crypt_info));
  // 用私钥解密
  pairCipher.createCipher(Cipher.DECRYPT_MODE,"RSA",pairCipher.getPrivateKey());
  not_crypt_info = pairCipher.Crypt(crypt_info);
  System.out.println("解密后的明文:       " + new String(not_crypt_info));
 }

 /**
  * 生成公钥和私钥
  */
 public void createPublicAndPrivateKey(String alg) {
  try {
   KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(alg);
   SecureRandom random = new SecureRandom();
   keyPairGenerator.initialize(SIZE, random);
   KeyPair keyPair = keyPairGenerator.generateKeyPair();
   privateKey = keyPair.getPrivate();
   publicKey = keyPair.getPublic();
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 创建加密/解密算法
  */
 public void createCipher(int mode , String alg , Key key) {
  try {
   cipher = Cipher.getInstance(alg);
   cipher.init(mode,key);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (NoSuchPaddingException e) {
   e.printStackTrace();
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 加密/解密信息
  */
 public byte[] Crypt(byte[] in){
  try {
   return cipher.doFinal(in);
  } catch (IllegalBlockSizeException e) {
   e.printStackTrace();
  } catch (BadPaddingException e) {
   e.printStackTrace();
  }
  return null;
 }

 public PrivateKey getPrivateKey() {
  return privateKey;
 }

 public PublicKey getPublicKey() {
  return publicKey;
 }
}
1.2.3 公钥私钥和对称密钥加解密结合使用
由于公钥私钥加解密要比对称密钥加解密慢,因此我们将公钥私钥和对称密钥加解密结合使用。
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;

public class PairCipher {
 private Key key = null ;
 private PrivateKey privateKey = null ;
 private PublicKey publicKey = null ;
 private Cipher cipher = null ;
 private static int SIZE = 514 ;
 
 public static void main(String[] args) {
  PairCipher pairCipher = new PairCipher();
  String information = "欢迎大家批评";
  byte[] crypt_key = null;              // 加密后的密码
  Key _key = null ;                        // 解密后的key
  byte[] crypt_info = null;             // 加密后的密文
  byte[] not_crypt_info = null;      // 解密后的明文
  
  System.out.println("要加密的信息:       " + information);
  // 创建密码
  pairCipher.CreateRandomRegularKey("AES");
  
  // 用户密码加密明文
  pairCipher.createCipher(Cipher.ENCRYPT_MODE,"AES",pairCipher.getKey());
  crypt_info = pairCipher.Crypt(information.getBytes());
  System.out.println("加密后的密文:       " + new String(crypt_info));
  
  // 创建公钥和私钥
  pairCipher.createPublicAndPrivateKey("RSA");
  
  // 用公钥加密密码
  pairCipher.createCipher(Cipher.WRAP_MODE,"RSA",pairCipher.getPublicKey());
  crypt_key = pairCipher.enCryptKey(pairCipher.getKey());
  System.out.println("加密后的密钥:       " + new String(crypt_key));
  
  // 用私钥解密密码
  pairCipher.createCipher(Cipher.UNWRAP_MODE,"RSA",pairCipher.getPrivateKey());
  _key = pairCipher.deCryptKey(crypt_key,"AES");
  
  // 用解密后的密码解密密文
  pairCipher.createCipher(Cipher.DECRYPT_MODE,"AES",_key);
  not_crypt_info = pairCipher.Crypt(crypt_info);
  System.out.println("解密后的明文:       " + new String(not_crypt_info));
 }

 /**
  * 生成公钥和私钥
  */
 public void createPublicAndPrivateKey(String alg) {
  try {
   KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(alg);
   SecureRandom random = new SecureRandom();
   keyPairGenerator.initialize(SIZE, random);
   KeyPair keyPair = keyPairGenerator.generateKeyPair();
   privateKey = keyPair.getPrivate();
   publicKey = keyPair.getPublic();
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 随机生成对称密钥
  */
 public void CreateRandomRegularKey(String alg){
  try {
   KeyGenerator keyGenerator = KeyGenerator.getInstance(alg);
   SecureRandom secureRandom = new SecureRandom();
   keyGenerator.init(secureRandom);
   key = keyGenerator.generateKey();
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 创建加密/解密算法
  */
 public void createCipher(int mode , String alg , Key key) {
  try {
   cipher = Cipher.getInstance(alg);
   cipher.init(mode,key);
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  } catch (NoSuchPaddingException e) {
   e.printStackTrace();
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * 加密/解密信息
  */
 public byte[] Crypt(byte[] in){
  try {
   return cipher.doFinal(in);
  } catch (IllegalBlockSizeException e) {
   e.printStackTrace();
  } catch (BadPaddingException e) {
   e.printStackTrace();
  }
  return null;
 }
 
 /**
  * 加密密钥
  */
 public byte[] enCryptKey(Key key){
  try {
   return cipher.wrap(key);
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  } catch (IllegalBlockSizeException e) {
   e.printStackTrace();
  }
  return null ;
 }
 
 /**
  * 解密密钥
  */
 public Key deCryptKey(byte[] key,String alg){
  try {
   return cipher.unwrap(key, alg,Cipher.SECRET_KEY);
  } catch (InvalidKeyException e) {
   e.printStackTrace();
  } catch (NoSuchAlgorithmException e) {
   e.printStackTrace();
  }
  return null ;
 }

 public Key getKey() {
  return key;
 }

 public PrivateKey getPrivateKey() {
  return privateKey;
 }

 public PublicKey getPublicKey() {
  return publicKey;
 }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值