标签:
加密、数字签名基本概念:
加密:
密码常用术语: 明文,密文,加密,加密算法,加密秘钥,解密,解密算法,解密秘钥,
密码分析:分析密文从而推断出明文或秘钥的过程
主动攻击:入侵密码系统,采用伪造,修改,删除等手段向系统注入假消息进行欺骗。(对密文有破坏作用)
被动攻击:对一个保密系统采取截获密文并对其进行分析和攻击。(对密文没有破坏作用)
密码体制:由明文/密文/密钥空间,加密算法和解密算法五部分构成
密码协议:也称安全协议,以密码学为基础的消息交换通信协议
密码系统:指用于加密、解密的系统。
柯克霍夫原则:密码的安全基于密钥而不是算法的保密。现代密码学设计的基本原则密码分类:
古典密码:以字符块为基本加密单元;现代密码:以信息块为基本加密单元
受限算法:保密性基于算法,应用军事,属于古典密码;基于密钥算法:算法公开,密钥保密。属于现在密码。
对称密码:加解密密钥相同;非对称密码:密钥分为公钥私钥。
分组密码:明文分组,对每块加密;流密码:也称序列密码,每次加密一位或一个字节。
散列函数:用来验证数据的完整性,长度不限,哈希值容易算,运算过程不可逆。如,md5,sha,mac
数字签名:针对以数字的形式存储的消息进行的处理。OSI安全体系:
osi:应表会传网数物
安全机制:认证,数字签名,访问控制,路由控制,加密机制,业务流填充,数据完整性,公证
安全服务:认证(来源鉴别),访问控制,数据保密性服务,数据完整性服务,抗否认性服务tcp/ip:应传网网,每一层都有相应的安全体系结构
数字签名:带有密钥(公钥、私钥,私钥签名,公钥验证)的消息摘要算法
OSI参考模型,验证数据完整性、认证数据来源、抗否认
java的安全组成:jca、jce、jsse、jass
ava的安全组成:jca(加密架构),jce(加密扩展),jsse(安全套接扩展,基于ssl),jaas(鉴别与安全服务)
jdk相关包:java.security:消息摘要
javax.crypto:安全消息摘要,消息认证(鉴别)码
java.net.ssl:java套接字,常用类HttpsURLConnection、SSLContext第三方扩展:
Bouncy Castle两种支持方案
1.在jdk中的jre\lib\security\java.security文件配置Provider
2.Security类中使用addProvider 或 insertProviderAt方法
Commons Codec
Apache
Base64、二进制、十六进制、字符集编码
Url编码/解码
常见算法:base64、md/sha/mac
base64算法:
算法实现:jdk、Commons Codec、Bouncy Castle
jdk:new BASE64Encoder().encode(src.getBytes());new BASE64Decoder().decodeBuffer(result);
Commons Codec:Base64.encodeBase64(src.getBytes());Base64.decodeBase64(result);
Bouncy Castle:Base64.encode(src.getBytes());Base64.decode(result);
消息摘要算法:md、sha(安全散列算法)、mac(含有密钥的散列算法)。
作用:验证数据的完整性;数字签名的核心算法。md用于存储数据库密码,sha常用于证书。
// MD5(128)或sha加密: try { MessageDigest messageDigest = MessageDigest.getInstance("MD5");// sha加密使用“SHA” messageDigest.reset(); // 重置摘要以供再次使用 messageDigest.update("2".getBytes("UTF-8"));// 使用指定的字节更新摘要。 byte[] digest = messageDigest.digest(src.getBytes("UTF-8"));// 通过执行诸如填充之类的最终操作完成哈希计算。 System.out.println("md5加密:" + CommonUtils.toHex(digest)); } catch (Exception e) { e.printStackTrace(); }
// mac加密: try { KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");// 初始化KeyGenerator SecretKey secretKey = keyGenerator.generateKey();// 产生密钥 // byte[] key = secretKey.getEncoded();//获得密钥 byte[] key = Hex.decodeHex(new char[] { ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘, ‘a‘ }); SecretKey restoreSecretKey = new SecretKeySpec(key, "HmacMD5");// 还原密钥 Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());// 实例化MAC mac.init(restoreSecretKey);// 初始化Mac byte[] hmacMD5Bytes = mac.doFinal(src.getBytes());// 执行摘要 System.out.println("jdk hmacMD5 : " + Hex.encodeHexString(hmacMD5Bytes)); } catch (Exception e) { e.printStackTrace(); }
加密、签名常用类:
密钥生成器:KeyGenerator/KeyPairGenerator
密钥:SecretKey、KeyPair
密钥规范:DESKeySpec/SecretKeySpec/PBEKeySpec、PKCS8EncodedKeySpec/X509EncodedKeySpec
密钥工厂:SecretKeyFactory、KeyFactory
加解密:Cipher
签名:Signature
加密参数规范:PBEParameterSpec、DHParameterSpec
密钥协定(或密钥交换)协议:KeyAgreement
其他类:Security、SecureRandom
类说明:
Security:类集中了所有的安全属性和常见的安全方法。其主要用途之一是管理提供者
SecureRandom:提供强加密随机数生成器KeyGenerator:提供(对称)密钥生成器的功能
SecretKey:(对称)密钥
SecretKeyFactory:用于密钥、密钥规范的互转。(如KeySpec和SecretKey)KeyPairGenerator:用于生成公钥和私钥对
KeyPair:简单的密钥对
PublicKey/PrivateKey:公钥/私钥
KeyFactory:用于密钥、密钥规范的互转。(如KeySpec、公钥私钥)
KeyAgreement:此类提供密钥协定(或密钥交换)协议的功能。KeySpec:组成加密密钥的密钥内容的(透明)规范,是一个接口
DESKeySpec:此类指定一个 DES 密钥
SecretKeySpec:此类以与 provider 无关的方式指定一个密钥,继承了KeySpec和SecretKey,可以直接当做SecretKey使用
PBEKeySpec:可随同基于密码的加密法 (PBE) 使用的供用户选择的密码
PKCS8EncodedKeySpec:专用密钥的 ASN.1 编码,PKCS#8 中定义的 PrivateKeyInfo;
X509EncodedKeySpec:进行编码的公用密钥的 ASN.1 编码,X.509 标准中定义的SubjectPublicKeyInfo
;
Cipher:此类为加密和解密提供密码功能
Signature:提供数字签名算法功能PBEParameterSpec:指定随同以密码为基础的加密法 (PBE) 使用的参数集合
DHParameterSpec:指定随同 Diffie-Hellman 算法使用的参数集合
对称加密:DES、3DES、AES、PBE
常用加密算法:
DES:(Data Encryption Standard)数据加密标准
3DES:密钥加长,多次叠加
AES:ssh协议,多用于移动,高级
PBE:基于口令加密,可以额外加盐DES、3DES、AES加密流程:
发送方—>构建密钥对-》公布密钥给接收方—>使用密钥对数据加密-》发送加密数据给接收方。
接收方—》接收密钥和加密数据解密数据PBE加密流程:
发送方—>构建密钥-》公布密钥给接收方-》构建盐—>使用口令,盐对数据加密-》发送盐、加密数据给接收方。
接收方—》使用密钥、口令,盐解密数据DES、3DES、AES加密code:
// jdkDES加密 public static void jdkDES() { try { // 生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // key的转换 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); SecretKey convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdkDES加密:" + CommonUtils.toHex(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("jdkDES加密:" + new String(result)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } // bcDES加密 public static void bcDES() { try { Security.addProvider(new BouncyCastleProvider()); // 生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("DES", "BC"); keyGenerator.getProvider(); keyGenerator.init(56); SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // key的转换 DESKeySpec desKeySpec = new DESKeySpec(bytesKey); SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); SecretKey convertSecretKey = factory.generateSecret(desKeySpec); // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("bcDES加密:" + CommonUtils.toHex(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("bcDES加密:" + new String(result)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } // jdkAES加密 public static void jdkAES() { try { // 生成key KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); keyGenerator.init(new SecureRandom());// 默认长度 SecretKey secretKey = keyGenerator.generateKey(); byte[] bytesKey = secretKey.getEncoded(); // key的转换 Key convertSecretKey = new SecretKeySpec(bytesKey, "AES"); // 加密 Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdkAES加密:" + CommonUtils.toHex(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("jdkAES加密:" + new String(result)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
PBE加密code:
// PBE加密 private static void jdkPBE() { try { // 初始化加盐 SecureRandom random = new SecureRandom(); byte[] salt = random.generateSeed(8); // 口令与密钥 String password = "psw"; PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray()); SecretKeyFactory factory = SecretKeyFactory .getInstance("PBEWITHMD5andDES"); SecretKey key = factory.generateSecret(pbeKeySpec); // 加密 PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(salt, 100); Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES"); cipher.init(Cipher.ENCRYPT_MODE, key, pbeParameterSpec); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdkPBE加密:" + CommonUtils.toHex(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, key, pbeParameterSpec); result = cipher.doFinal(result); System.out.println("jdkPBE加密:" + new String(result)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
非对称加密:DH、RSA、ELGamel、ECC
加密算法:
DH(Diffie-Hellman)密钥交换算法
RSA:基于因子分解。一般私钥加密,公钥解密;也可以公钥加密,私钥解密。
ELGamel:基于离散对数
ECC( Elliptic curve Cryptography) 椭圆曲线加密DH加密流程:
初始化DH算法密钥对:
发送方—>构建发送方密钥-》公布发送方密钥给接收方-》使用接收者公钥构建发送方本地密钥
接收方—》使用发送方密钥密钥构建接收方密钥-》公布接收者公钥给发送方—》构建接收方本地密钥DH算法加密消息传递:
发送方—>使用本地密钥加密消息—》发送加密消息给接收方
接收方—》使用本地密钥解密消息
RSA加密流程:
私钥加密,公钥解密
发送方—>私钥钥解密加密消息—》发送加密消息给接收方
接收方—》使用公钥解密消息公钥加密,私钥解密
发送方—>公钥钥解密加密消息—》发送加密消息给接收方
接收方—》使用私钥解密消息DH加密code:
// jdkDH加密 private static void jdkDH() { try { // 1.初始化发送方密钥 KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH"); senderKeyPairGenerator.initialize(512); KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair(); byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();///发送方公钥,发送给接收方(网络、文件。。。) //2.初始化接收方密钥 KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc); PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec = ((DHPublicKey)receiverPublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeypair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiverKeypair.getPrivate(); byte[] receiverPublicKeyEnc = receiverKeypair.getPublic().getEncoded(); //3.密钥构建 KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH"); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receiverPublicKey, true); SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES"); KeyFactory senderKeyFactory = KeyFactory.getInstance("DH"); x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc); PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH"); senderKeyAgreement.init(senderKeyPair.getPrivate()); senderKeyAgreement.doPhase(senderPublicKey, true); SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES"); if(Objects.equals(senderDesKey, receiverDesKey)){ System.out.println("双方密钥相同"); } //4.加密 Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, senderDesKey); byte[] result = cipher.doFinal(src.getBytes()); System.out.println("jdk dh 加密:"+CommonUtils.toHex(result)); //5.解密 cipher.init(Cipher.DECRYPT_MODE, receiverDesKey); result = cipher.doFinal(result); System.out.println("jdk dh 解密:"+new String(result)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
RSA加密code:
public static void jdkRSA() { try { //1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate(); System.out.println("Public Key : " + Base64.encodeBase64String(rsaPublicKey.getEncoded())); System.out.println("Private Key : " + Base64.encodeBase64String(rsaPrivateKey.getEncoded())); //2.私钥加密、公钥解密——加密 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("私钥加密、公钥解密——加密 : " + Base64.encodeBase64String(result)); //3.私钥加密、公钥解密——解密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, publicKey); result = cipher.doFinal(result); System.out.println("私钥加密、公钥解密——解密:" + new String(result)); //4.公钥加密、私钥解密——加密 x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("RSA"); publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); result = cipher.doFinal(src.getBytes()); System.out.println("公钥加密、私钥解密——加密 : " + Base64.encodeBase64String(result)); //5.公钥加密、私钥解密——解密 pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); keyFactory = KeyFactory.getInstance("RSA"); privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, privateKey); result = cipher.doFinal(result); System.out.println("公钥加密、私钥解密——解密:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } }
数字签名:RSA、DSA、ECDSA
DSS(Data Signature Standard)数字签名标准
常用签名算法:RSA、DSA、ECDSA
RSA:非对称算法,基于RSA算法的消息摘要算法,如MD5算法
DSA(Data Signature Algorithm)数字签名算法:DSA仅包含数字签名,不包含加解密
ECDSA(elliptic curve digital signature algorithm) 椭圆曲线数字签名算法:速度快,强度高,签名短RSA签名流程:
发送方—>构建密钥对-》公布密钥给接收方—>使用私钥对数据签名-》发送签名、数据给接收方。
接收方—》使用公钥、签名验证数据RSA签名code
/** * 使用rsa签名 发送方—>构建密钥对-》公布密钥给接收方。 发送方—>使用私钥对数据签名-》发送签名、数据给接收方—》接收方使用公钥、签名验证数据 */ private static void testJdkRSA() { try { // 初始化签名 KeyPairGenerator keyPairGenerator = KeyPairGenerator .getInstance("RSA"); keyPairGenerator.initialize(512); 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("jdk ras sign:" + CommonUtils.toHex(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("jdk rsa verify:" + bool); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 使用dsa签名 */ private static void testJdkDSA() { try { // 初始化签名 KeyPairGenerator keyPairGenerator = KeyPairGenerator .getInstance("DSA"); keyPairGenerator.initialize(512); KeyPair keyPair = keyPairGenerator.generateKeyPair(); DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic(); DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate(); // 2.执行签名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( dsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PrivateKey privateKey = keyFactory .generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance("SHA1withDSA"); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk das sign:" + CommonUtils.toHex(result)); // 3.验证签名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec( dsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("DSA");// 为了数据的完整性 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); signature = Signature.getInstance("SHA1withDSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk rsa verify:" + bool); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void testJdkECDSA() { try { // 初始化签名 KeyPairGenerator keyPairGenerator = KeyPairGenerator .getInstance("EC"); keyPairGenerator.initialize(256); KeyPair keyPair = keyPairGenerator.generateKeyPair(); ECPublicKey dsaPublicKey = (ECPublicKey) keyPair.getPublic(); ECPrivateKey dsaPrivateKey = (ECPrivateKey) keyPair.getPrivate(); // 2.执行签名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( dsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance("EC"); PrivateKey privateKey = keyFactory .generatePrivate(pkcs8EncodedKeySpec); Signature signature = Signature.getInstance("SHA1withECDSA"); signature.initSign(privateKey); signature.update(src.getBytes()); byte[] result = signature.sign(); System.out.println("jdk ec sign:" + CommonUtils.toHex(result)); // 3.验证签名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec( dsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance("EC");// 为了数据的完整性 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); signature = Signature.getInstance("SHA1withECDSA"); signature.initVerify(publicKey); signature.update(src.getBytes()); boolean bool = signature.verify(result); System.out.println("jdk rsa verify:" + bool); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
标签:
原文地址:http://www.cnblogs.com/cjcblogs/p/4805996.html