java安全

来源:互联网 发布:论文数据库 编辑:程序博客网 时间:2024/06/14 03:19

1 Provider称为提供者类

1.1 负责加密算法、密钥算法


1.2 jdk本身就有10个provider


security.provider.1=sun.security.provider.Sun

security.provider.2=sun.security.rsa.SunRsaSign

security.provider.3=sun.security.ec.SunEC

security.provider.4=com.sun.net.ssl.internal.ssl.Provider

security.provider.5=com.sun.crypto.provider.SunJCE

security.provider.6=sun.security.jgss.SunProvider

security.provider.7=com.sun.security.sasl.Provider

security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI

security.provider.9=sun.security.smartcardio.SunPCSC

security.provider.10=sun.security.mscapi.SunMSCAPI


常用的第三方的BouncyCastleProvider也是很强悍的,但是需要手动添加到环境


1.3 provider的结构大致如下: 

一个name

一个info

多个service

        一个service对应多个Algorithm:RSA AES MD5withRSA等


2 Security负责管理Provider

添加第三方provider

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());



3 Key所有密钥的顶层接口

3.1 生成一个key指定两个属性

(1)它使用什么算法:

        如AES、DES、RSA等


(2)它使用什么编码:

        密钥的码形式:X509、PKCS#8


3.2 下面接口方法可以窥伺Key结构

Key.getAlgorithm()返回算法名词:RSA

Key.getFormat返回编码格式名称:'PKCS#8'等

Key.getEncoded()返回密钥编码后的byte[],可以用base64编码后可见
        

3.3 三大接口继承自Key

SecretKey(对称加密顶层接口),Publickey\PrivateKey(非对称加密的顶层接口)


4 非对称密钥生成

4.1 KeyPair是非对称密钥的扩展

4.2 KeyPairGenerator生成密钥对

KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");

keyPairGenerator.initialize(1024);

KeyPair keyPair = keyPairGenerator.generateKeyPair();

PrivateKey privateKey = keyPair.getPrivate();

PublicKey publicKey = keyPair.getPublic();


4.3 KeyFactory生成私钥(公钥流程一样,配置略有不同)

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(btye[] encode);// 私钥特定编码后的btye[]

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);



5 SecureRandom 

为何在安全方便不能使用普通的Random?

为何在安全方便不能使用
普通的Random使用的是Linear Congruential Generator线性同余发生器,实际上这个随机数是可预测的,所以在安全领域,一般使用SecureRandom



6 Chiper 暗号

使用密钥对明文、密文实现具体的加密、解密过程。需要初始化模式

cipher.init(Cipher.DECRYPT_MODE, publicKey);// 公钥解密

cipher.init(Cipher.ENCRYPT_MODE, privateKey);// 私钥加密


7 keySpec

密钥编码规范的顶层接口

keySpec  -> EncodedKeySpec(抽象) ->两实现类(1)X509EncodedKeySpec 构建公钥编码规范(2)PKCS8EncodedKeySpec 构建私钥编码规范 
keySpec -> SecretKeySpec 兼容所有的对称加密密钥编码规范
keySpec -> DESKeySpec 仅仅是DES编码规范


8 Signature 

封装了签名和验签,实际上也可以自己实现杂抽和非对称算法实现

(1)指定公钥和私钥

(2)指定签名算法:MD5withRSA等

签名

String info = "i am jack";

Signature signature = Signature.getInstance("MD5withRSA", new BouncyCastleProvider());

signature.update(info.getBytes("utf-8"));

byte[] signByte = signature.sign();

String sign = Base64.encodeBase64String(signByte);

验签:

String sign = "xhajklak";

String info = "i am jack";

Signature signature = Signature.getInstance("MD5withRSA", new BouncyCastleProvider());

signature.initVerify(publicKey);

signature.update(info.getBytes("utf-8"));

boolean status = signature.verify(Base64.decodeBase64(sign));


9 贴代码

//----------------签名-------------------


PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream("privkey.pem")));

PemObject pemObject = pemReader.readPemObject();

byte[] content = pemObject.getContent();

PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);

Provider provider = new BouncyCastleProvider();

Security.addProvider(provider);

KeyFactory factory = KeyFactory.getInstance("RSA","BC");

privateKey = factory.generatePrivate(privKeySpec);


String info = "i am jack";

String md5 = Base64.encodeBase64String(md5Digest.digest(info.getBytes("utf-8")));

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, privateKey);

byte[] signByte = Base64.decodeBase64(md5);

byte[] digestByte = cipher.doFinal(signByte);

String sign =  Base64.encodeBase64String(digestByte);


//--------------验签------------------


PemReader pemReader = new PemReader(new InputStreamReader(new FileInputStream("public.pem")));

PemObject pemObject = pemReader.readPemObject();

byte[] content = pemObject.getContent();

X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content);

Provider provider = new BouncyCastleProvider();

Security.addProvider(provider);

KeyFactory factory = KeyFactory.getInstance("RSA","BC");// BC是使用BouncyCastle的意思

PublicKey publicKey = factory.generatePublic(pubKeySpec);


String sign = "Vl7cDe1mdiT6BBGJOt9oXIigVh4=";

String info = "i am jack";

Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, publicKey);

byte[] signByte = Base64.decodeBase64(sign);

byte[] digestByte = cipher.doFinal(signByte);

String md5Temp = Base64.encodeBase64String(digestByte);


MessageDigest md5Digest = MessageDigest.getInstance("MD5");

String md5 = Base64.encodeBase64String(md5Digest.digest(info.getBytes("utf-8")));

if(md5Temp.equals(md5)){
// 验签成功
}


为何在安全方便不能使用