对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信性至关重要。
特点
public static void desSecret() throws NoSuchAlgorithmException { // 密钥生成器 KeyGenerator key = KeyGenerator.getInstance("DESede"); /** * 初始化密钥生成器 该步骤一般指定密钥的长度。如果该步骤省略的话, 会根据算法自动使用默认的密钥长度。指定长度时, * 若第一步密钥生成器使用的是“DES”算法,则密钥长度必须是56位; * 若是“DESede”,则可以是112或168位,其中112位有效;若是“AES”, 可以是128, * 192或256位;若是“Blowfish”,则可以是32至448之间可以被8整除的数; * “HmacMD5”和“HmacSHA1”默认的密钥长度都是64个字节 */ key.init(168); // 生成密钥 SecretKey secret = key.generateKey(); FileOutputStream s; try { s = new FileOutputStream("D://des-pri.key"); ObjectOutputStream st = new ObjectOutputStream(s); st.writeObject(secret); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static byte[] desEncrypt(String str) throws Exception { byte[] miby = null; FileInputStream s = new FileInputStream("D://des-pri.key"); ObjectInputStream st = new ObjectInputStream(s); SecretKey secret = (SecretKey) st.readObject(); // 工厂模式获取Cipher实例 密码器 Cipher cp = Cipher.getInstance("DESede"); // 初始化cipher ENCRYPT_MODE表示加密DECRYPT_MODE解密 后面一个参数是密钥 cp.init(Cipher.ENCRYPT_MODE, secret); byte[] by = str.getBytes("utf-8"); // 对字节码机密 miby就是加密后的字节码 miby = cp.doFinal(by); return miby; } public static String desUnEncrypt(byte[] sct) throws Exception { // 通过提供的密钥文件 获取密钥对象 进行解密 FileInputStream s = new FileInputStream("D://des-pri.key"); ObjectInputStream st = new ObjectInputStream(s); SecretKey secret = (SecretKey) st.readObject(); // 工厂模式获取Cipher实例 密码器 Cipher cp = Cipher.getInstance("DESede"); // 初始化cipher ENCRYPT_MODE表示加密DECRYPT_MODE解密 后面一个参数是密钥 cp.init(Cipher.DECRYPT_MODE, secret); // 对密文字节码进行解密 如果密码写入文件可以使用文件流读写成一个数组 byte[] miby = cp.doFinal(sct); // 获取密文字符串 String minwen = new String(miby, "utf-8"); return minwen; }
非对称加密:非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥
特点
A想将目标数据传给B,此时A需要准备1和2两部分
public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; // 初始化RSA非对称密钥 public static void generaterA() { try { KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); SecureRandom secrand = new SecureRandom(); keygen.initialize(1024, secrand); KeyPair keys = keygen.genKeyPair(); PublicKey pubkey = keys.getPublic(); PrivateKey prikey = keys.getPrivate(); String strpk = new String(Base64.encodeBase64(pubkey.getEncoded())); String strprivk = new String(Base64.encodeBase64(prikey.getEncoded())); DesSecretUtil.saveData(strpk.getBytes(), "D://rsa-pub_A.pem"); DesSecretUtil.saveData(strprivk.getBytes(), "D://rsa-pri_A.pem"); } catch (java.lang.Exception e) { System.out.println("生成密钥对失败"); e.printStackTrace(); } } /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = Base64.decodeBase64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); // 加密由base64编码的签名 return Base64.encodeBase64String(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = Base64.decodeBase64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(Base64.decodeBase64(sign)); } /** * 解密<br> * 用私钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = Base64.decodeBase64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用公钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = Base64.decodeBase64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { // base64 解密公钥 byte[] keyBytes = Base64.decodeBase64(key); X509EncodedKeySpec x509Key = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509Key); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用私钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = Base64.decodeBase64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } public static void main(String[] args) { // A向B发送数据 try { byte[] pub_A = DesSecretUtil.readData("D://rsa-pub_A.pem"); byte[] pri_A = DesSecretUtil.readData("D://rsa-pri_A.pem"); byte[] pub_B = DesSecretUtil.readData("D://rsa-pub_B.pem"); byte[] pri_B = DesSecretUtil.readData("D://rsa-pri_B.pem"); String str = "开始测试"; byte[] data = str.getBytes("UTF-8"); //拿B的公钥加密 byte[] encrptData = encryptByPublicKey(data, new String(pub_B)); System.out.println("加密后Base64数据:"+Base64.encodeBase64String(encrptData)); //拿B的私钥解密 byte[] decrptData = decryptByPrivateKey(encrptData,new String(pri_B)); System.out.println("解密后明文:"+new String(decrptData,"UTF-8")); // A的私钥数字签名 String sign = sign(encrptData,new String(pri_A)); // 加密由base64编码的签名 System.out.println("加密由base64编码的签名 :"+sign); // A的公钥数字签名验证是否信息被篡改 boolean flag = verify(decrptData,new String(pub_A),sign); System.out.println("数字签名验证 :"+flag); } catch (Exception e) { e.printStackTrace(); } }
原文:http://www.cnblogs.com/ks-apper/p/5181463.html