`
沙舟狼客
  • 浏览: 157728 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

开发一个JCE的Provider

阅读更多

1、开发环境ubuntu+eclipse+openJDK

本来想在xp下开发,但是JDK1.6中有层层限制:JCA对外出口但是JCE对外不出口,当你实现后调用Cipher会报如下错误:

Exception in thread "main" java.lang.SecurityException: JCE cannot authenticate the provider SecureProvider
	at javax.crypto.Cipher.getInstance(DashoA13*..)
	at com.ligson.test.SimpleTest.main(SimpleTest.java:19)
Caused by: java.util.jar.JarException: Cannot parse file:/E:/code/itrusca/MyProvider/target/classes/
	at javax.crypto.SunJCE_c.a(DashoA13*..)
	at javax.crypto.SunJCE_b.b(DashoA13*..)
	at javax.crypto.SunJCE_b.a(DashoA13*..)
	... 2 more

 意思是让你去用自己产生的CSR提交到SUN的CA中心(IBM旗下也有)产生一张证书,进行代码签名(据我找到的信息,他一般是不会向你颁发证书的,也许你会说BouncyCastle就有自己的Provider,但是人家不是中国的)

2、Provider的实现

package com.ligson.provider;

import java.io.IOException;
import java.net.URL;
import java.security.AccessController;
import java.security.AuthProvider;
import java.security.CodeSource;
import java.security.PrivilegedAction;
import java.security.Provider;
import java.security.SecurityPermission;
import java.util.jar.JarException;

import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;

import com.ligson.jce.impl.SM3MessageDigest;

public final class SecureProvider extends AuthProvider {

	private static String name = "SecureProvider";
	private static String info = "this is a test provider for sm2/sm3";
	private static double version = 1.0d;

	public SecureProvider() {
		super(name, version, info);
		// this.putService(s);
                //授权
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
                                //放入自己的基础实现类
                                //格式:类型.算法
				put("Cipher.SM2", "com.ligson.jce.impl.SM2Cipher");
				put("MessageDigest.SM3", SM3MessageDigest.class.getName());
				put("Cipher.Simple", "com.ligson.provider.SimpleCipher");
				put("KeyGenerator.Simple",
						"com.ligson.provider.SimpleKeyGenerator");
				return null;
			}

		});

	}
	private static URL getClassURL(final Class<?> clazz) {
		return AccessController.doPrivileged(new PrivilegedAction<URL>() {
			public URL run() {
				CodeSource cs = clazz.getProtectionDomain().getCodeSource();
				return cs.getLocation();
			}
		});
	}
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public String getName() {
		return name;
	}

	public String getInfo() {
		return info;
	}

	public double getVersion() {
		return version;
	}

	public static interface Tst {
	}

	@Override
	public void login(Subject subject, CallbackHandler handler)
			throws LoginException {
		SecurityManager sm = System.getSecurityManager();
		sm.checkPermission(new SecurityPermission("authProvider."
				+ this.getName()));
	}

	@Override
	public void logout() throws LoginException {
		// TODO Auto-generated method stub

	}

	@Override
	public void setCallbackHandler(CallbackHandler handler) {
		// TODO Auto-generated method stub

	};

}

 3、SimpleCipher的实现,原理很简单,就是把输入的byte[]的每一个byte元素加上一个随机数,解密的时候再减去

package com.ligson.provider;

import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.CipherSpi;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;

public class SimpleCipher extends CipherSpi {
	private int mode;
	private Key key;
	private byte[] in;

	@Override
	protected byte[] engineDoFinal(byte[] arg0, int arg1, int arg2)
			throws IllegalBlockSizeException, BadPaddingException {
		return implDoFinal();
	}

	@Override
	protected int engineDoFinal(byte[] arg0, int arg1, int arg2, byte[] arg3,
			int arg4) throws ShortBufferException, IllegalBlockSizeException,
			BadPaddingException {
		return 0;
	}

	@Override
	protected int engineGetBlockSize() {
		return 0;
	}

	@Override
	protected byte[] engineGetIV() {
		return null;
	}

	@Override
	protected int engineGetOutputSize(int arg0) {
		return 0;
	}

	@Override
	protected AlgorithmParameters engineGetParameters() {
		return null;
	}

	@Override
	protected void engineInit(int arg0, Key arg1, SecureRandom arg2)
			throws InvalidKeyException {
		implInit(arg0, arg1);
	}

	@Override
	protected void engineInit(int arg0, Key arg1, AlgorithmParameterSpec arg2,
			SecureRandom arg3) throws InvalidKeyException,
			InvalidAlgorithmParameterException {
		implInit(arg0, arg1);
	}

	@Override
	protected void engineInit(int arg0, Key arg1, AlgorithmParameters arg2,
			SecureRandom arg3) throws InvalidKeyException,
			InvalidAlgorithmParameterException {
		implInit(arg0, arg1);
	}

	@Override
	protected void engineSetMode(String arg0) throws NoSuchAlgorithmException {
	}

	@Override
	protected void engineSetPadding(String arg0) throws NoSuchPaddingException {
	}

	@Override
	protected byte[] engineUpdate(byte[] arg0, int arg1, int arg2) {
		return implUpdate(arg0, arg1, arg2);
	}

	@Override
	protected int engineUpdate(byte[] arg0, int arg1, int arg2, byte[] arg3,
			int arg4) throws ShortBufferException {
		return 0;
	}

	private void implInit(int mode, Key key) {
		this.mode = mode;
		if (key instanceof SimpleKey) {
			this.key = key;
		} else {
			throw new RuntimeException("key invalid!");
		}
	}

	private byte[] implUpdate(byte[] in, int offset, int len) {
		this.in = in;
		return in;
	}

	private byte[] implDoFinal() {
		SimpleKey simpleKey = (SimpleKey) key;
		if (mode == Cipher.ENCRYPT_MODE) {
			for (int i = 0; i < in.length; i++) {
				in[i] = (byte) (in[i] + simpleKey.offset);
			}
		} else if (mode == Cipher.DECRYPT_MODE) {
			for (int i = 0; i < in.length; i++) {
				in[i] = (byte) (in[i] - simpleKey.offset);
			}
		} else {
			throw new RuntimeException("mode must be encrypt or decrypt!");
		}
		return in;
	}

	public void init(int mode, Key key) {
		implInit(mode, key);
	}

	public void update(byte[] in, int offset, int len) {
		implUpdate(in, offset, len);
	}

	public byte[] doFinal() {
		return implDoFinal();
	}
}

 4、SimpleKey(只是一个简单的对称密钥)的实现,里面只保存随机的偏移量、长度等

 package com.ligson.provider;

import java.security.SecureRandom;

import javax.crypto.SecretKey;

public class SimpleKey implements SecretKey {
	protected int len;
	protected SecureRandom random;
	protected int offset;
	SimpleKey(SecureRandom random, int keySize,int offset) {
		this.len = keySize;
		this.random = random;
		this.offset = offset;
	}
	@Override
	public String getAlgorithm() {
		return "Simple";
	}

	@Override
	public String getFormat() {
		return "";
	}

	@Override
	public byte[] getEncoded() {
		byte[] b = new byte[len];
		random.nextBytes(b);
		return b;
	}

}

 5、SimpleKeyGenerator的实现

package com.ligson.provider;

import java.security.InvalidAlgorithmParameterException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.KeyGeneratorSpi;
import javax.crypto.SecretKey;

public class SimpleKeyGenerator extends KeyGeneratorSpi {
	private SecureRandom random = new SecureRandom();
	private int keySize = 128;
	private int offset = 3;
	@Override
	protected SecretKey engineGenerateKey() {
		offset = random.nextInt();
		return new SimpleKey(random,keySize,offset);
	}

	@Override
	protected void engineInit(SecureRandom secureRandom) {
		this.random = secureRandom;
	}

	@Override
	protected void engineInit(AlgorithmParameterSpec arg0, SecureRandom arg1)
			throws InvalidAlgorithmParameterException {
		throw new InvalidAlgorithmParameterException("no support operation");
	}

	@Override
	protected void engineInit(int keySize, SecureRandom secureRandom) {
		this.keySize = keySize;
		this.random = secureRandom;
	}

}

 

6、Provider的测试程序

SecureProvider provider = new SecureProvider();
Security.addProvider(provider);
KeyGenerator generator = KeyGenerator.getInstance("Simple",provider);
System.out.println(generator);
generator.init(512);
SecretKey secretKey = generator.generateKey();

System.out.println(Arrays.toString(secretKey.getEncoded()));

byte[] plain = "password".getBytes();
System.out.println(Arrays.toString(plain));
Cipher cipher = Cipher.getInstance("Simple");
cipher.init(Cipher.ENCRYPT_MODE,secretKey);
cipher.update(plain);
byte[] result = cipher.doFinal();

System.out.println(Arrays.toString(result));
cipher.init(Cipher.DECRYPT_MODE,secretKey);
cipher.update(result);
byte[] result2 = cipher.doFinal();
System.out.println(Arrays.toString(result2));
System.out.println(Arrays.equals(result2,plain));

 结果如下:


 

  • 大小: 14.4 KB
0
1
分享到:
评论

相关推荐

    解决java.lang.SecurityException: JCE cannot authenticate the provider BC问题

    在与银联的对接中,调试过程中报错或使用类似登入加密:java.lang.SecurityException: JCE cannot authenticate the provider BC 进行问题解决,里面包含 bcprov-jdk16-143.jar与bcprov-jdk15-135.jar与具体文件存放...

    org.bouncycastle.jar

    解决org/bouncycastle/jce/provider/bouncycastlepr错误专用。

    微信企业号开发JCE6

    微信企业号开发JCE6,JCE包需要根据自己的jdk版本下载,对应JDK6

    Java密码扩展的基础 JCE

    JAVA 加密 JCE Java密码扩展的基础 关于JCE的基础

    JCE cannot authenticate the provider BC相关包

    1.修改 jre/lib/security/java.security文件 security.provider.9=org.bouncycastle.jce.provider.BouncyCastleProvider, 2.添加2个扩展包到jre/lib/ext目录下:bcprov-jdk15-135.jar bcprov-jdk16-143.jar

    微信企业号开发jar包(不含JCE)

    微信企业号开发jar包(不含JCE),JCE包需要根据自己的jdk版本下载

    JCE包JCE工具库

    Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持

    jce-policy-8 JDK8安装JCE无限强度

    jce_policy-8.zip jar包,jdk,安全,security,oracle官网下载 稍微麻烦 上传供大家方便下载

    jce_policy-8 java jce

    JCE,Java Cryptography Extension 1.8, java jce8 java jce

    sunjce_provider.jar

    jar包下载地址 : http://www.rsdown.cn/down/164019.html 下载后将sunjce_provider.jar放入webapp/WEB-INF/lib中

    jboss7.1.1下报java.lang.SecurityException: JCE cannot authenticate the provider BC

    NULL 博文链接:https://lwpsoft.iteye.com/blog/2254348

    jce8-jce7.zip

    jce8、jce7下载 jdk8无政策限制权限文件,用于AES加密算法,AES加密扩展包因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件...

    jce_policy文件

    jce_policy-6.zip,jce_policy-8.zip,UnlimitedJCEPolicyJDK7.zip

    jce-jdk13-139.jar

    jce-jdk13-139.jar是提供给java扩展包,放至jre/lib/ext目录下,并..\jre\lib\security\java.security文件中在配置security.provider.11=org.bouncycastle.jce.provider.BouncyCastleProvider后使用

    Bouncy Castle 的JCE运行包

    免费的JCE提供者。Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包。它支持大量的密码术算法,并提供 JCE 1.2.1 的实现。因为 Bouncy Castle 被设计成轻量级的,所以从 J2SE 1.4 到 J2ME(包括 MIDP...

    JCE(jce_policy-8).zip

    jce_policy-8,JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。 它提供对对称、不对称、块和流密码的加密支持,它还...

    joomla JCE 繁体中文语言包

    joomla JCE最新版本2.3.2.4 繁体中文语言包

    jce6到8对应jar.zip

    jce6到8对应jar.zip,jce6、jce7、jce8对应的jar,详情可以参考https://stackoverflow.com/questions/38203971/javax-net-ssl-sslhandshakeexception-received-fatal-alert-handshake-failure

    JCE文件jdk6, jdk7

    官网下载地址是...JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。

    JCE 加密、解密算法

    JCE 加密、解密算法

Global site tag (gtag.js) - Google Analytics