本文演示自定义摘要和对称加密算法 PDS
pds 是我自己定义的一个算法名称
算法规则: 一个数A异或另一个数B两次,将返回该数A
JAVA自带加密算法结构
JAVA的加密算法,基本上由该文件所配置提供
java/jre/lib/security/java.security
该配置通过Security 类进行加载,默认配置如下:
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
每一行都是一个Provider,下面我们看一下如何将Provider作为服务加载到系统中
这两条配置是代表同一个服务,Alg.Alias 是用来配置别名的,如 SHA-1,SHA1是同一个含义一个意思
JAVA可以通Security加载的服务种类
目前定义了以下服务:
SecureRandom 随机数
Signature 签名
KeyPairGenerator 密钥对生成
MessageDigest 消息摘要
AlgorithmParameterGenerator 算法参数生成器
AlgorithmParameters 算法参数
KeyFactory
CertificateFactory
KeyStore
Policy 一般不用
Configuration
CertPathBuilder
CertPathValidator
CertStore
Cipher
SecretKeyFactory
SSLContext
自定义摘要PDS
我们需要实现一个MessageDigestSpi,这是规范
添加一个Provider注册到ProviderList中
注册一般通过Security实现
系统默认的一般不改动,也就是不改动JDK的配置文件
我们需要通代码的方式加入到JDK的服务中
public class PdsProvider extends Provider {
protected PdsProvider(String name, double version, String info) {
super(name, version, info);
}
public PdsProvider(){
super("PDS",1.0,"test");
put("MessageDigest.PDS","message.PDS");
}
}
MessageDigestSpi
public class PDS extends MessageDigestSpi {
@Override
protected void engineUpdate(byte input) {
}
@Override
protected void engineUpdate(byte[] input, int offset, int len) {
//返回一个固定摘要PDS
}
@Override
protected byte[] engineDigest() {
return "PDS".getBytes();
}
@Override
protected void engineReset() {
}
}
调用
Security.addProvider(new PdsProvider());
byte[] bs = MessageDigest.getInstance("PDS").digest("123".getBytes());
System.out.println(new String(bs));
自定义对称加密PDS
1.实现CipherSpi
通过Security注册
特殊处理,添加权限
调用
PDSCipher
package message;
import javax.crypto.*;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;
public class PDSCipher extends CipherSpi {
private int opmode;
private byte key = 123;
@Override
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
//ignore
}
@Override
protected void engineSetPadding(String padding) throws NoSuchPaddingException {
//ignore
}
@Override
protected int engineGetBlockSize() {
return 0;
}
@Override
protected int engineGetOutputSize(int inputLen) {
return inputLen;
}
@Override
protected byte[] engineGetIV() {
return new byte[0];
}
@Override
protected AlgorithmParameters engineGetParameters() {
return null;
}
@Override
protected void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
this.opmode = opmode;
}
@Override
protected int engineGetKeySize(Key key) throws InvalidKeyException {
return 8;
}
@Override
protected void engineInit(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
this.opmode = opmode;
}
@Override
protected void engineInit(int opmode, Key key, AlgorithmParameters params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException {
this.opmode = opmode;
}
@Override
protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
return new byte[0];
}
@Override
protected int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException {
return 0;
}
@Override
protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException {
byte[] rs = new byte[inputLen];
for(int i=0;i
rs[i] = (byte)(input[i] ^ key);
}
return rs;
}
@Override
protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
return 0;
}
}
PdsProvider
package message;
import java.lang.reflect.Field;
import java.security.Provider;
import java.util.Map;
public class PdsProvider extends Provider {
protected PdsProvider(String name, double version, String info) {
super(name, version, info);
}
public PdsProvider(){
super("PDS",1.0,"test");
put("MessageDigest.PDS","message.PDS");
//加入对称加密
put("Cipher.PDS","message.PDSCipher");
put("Cipher.PDS SupportedModes","ECB");
put("Cipher.PDS SupportedPaddings","NOPADDING");
//以下代码是因为权限的问题:版本 jdk8
try {
Class clazz = Class.forName("javax.crypto.JceSecurity");
Field field = clazz.getDeclaredField("verificationResults");
field.setAccessible(true);
Map map = (Map)field.get(clazz);
map.put(this,Boolean.TRUE);
}catch (Exception e){
e.printStackTrace();
}
}
}
调用
Security.addProvider(new PdsProvider());
Cipher cipher = Cipher.getInstance("PDS/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,(Key) null);
String text = "1233456";
byte[] enc = cipher.doFinal(text.getBytes());
System.out.println(Base64.getEncoder().encodeToString(enc));
cipher.init(Cipher.DECRYPT_MODE,(Key) null);
byte[] dec = cipher.doFinal(enc);
System.out.println(new String(dec));
//System.out.println(en);



