`
沙舟狼客
  • 浏览: 161653 次
  • 性别: 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
分享到:
评论

相关推荐

    sunjce_provider.jar

    `sunjce_provider.jar`是Oracle公司提供的一个默认的安全提供者,它实现了JCE的一系列接口,提供了大量的加密算法和服务。这个库文件包含了Sun公司的加密实现,包括对称加密、非对称加密、消息摘要、随机数生成器...

    JDK8 JCE 支持256位加密

    在JDK8中,JCE(Java Cryptography Extension)的一个关键更新是它开始支持256位加密算法,这在之前的版本中可能是受限的。这一增强对于那些需要处理大量敏感数据和要求更高安全性的应用程序来说是非常重要的。 JCE...

    sunjce_provider.rar

    标题中的“sunjce_provider.rar”是一个压缩包文件,它包含了一个名为“sunjce_provider.jar”的组件,以及一个“新建文本文档.txt”的文本文件。这个压缩包主要是为了解决在某些Java运行环境中遇到的问题,即“找不...

    com.sun.crypto.provider.SunJCE----jar包

    SunJCE是Java平台标准版(Java SE)的一个服务提供者,它实现了多种加密算法,包括对称加密、非对称加密、哈希函数以及密钥协议等。 在Java中,加密和解密操作是通过Cipher类来完成的,而Cipher类需要依赖于特定的...

    JAVA数据加密jar包之sunjce_provider.rar

    `sunjce_provider`是Java Cryptography Extension (JCE)的一部分,JCE是Java标准版(Java SE)的一个组件,扩展了Java的安全性,提供了强大的加密功能。`sunjce_provider`提供了一种实现这些加密算法的方式,开发者...

    com.sun.crypto.provider.SunJCE

    是Java加密技术中一个关键的组件,它属于Oracle JDK的内置安全提供者。这个组件在描述中提到的问题是关于类`com.sun.crypto.provider.SunJCE`的加载问题,该类在某些特定版本的JDK中可能缺失或无法直接使用。 ...

    sunjce_provider.zip

    "sunjce_provider.zip"是一个包含SUNJCE提供商实现的压缩包,主要文件为"sunjce_provider.jar",这个JAR文件包含了用于加密、解密、数字签名和密钥管理等操作的类和接口。 1. **Java Cryptography Architecture ...

    Java Service Provider实现

    4. **SecuritySupport**:`SecuritySupport`是另一个内部类,主要用于处理与安全相关的操作,如访问系统属性、检查权限等。在SPI的上下文中,它确保了在加载服务提供者时遵循正确的安全性规则。 二、SPI的使用步骤 ...

    使用Java开发和信息安全相关的程序

    JCE是一个可扩展的框架,允许开发者自定义加密算法的实现,这些实现被称为JCE Provider。Sun公司提供了基础的提供者,但Bouncy Castle Provider被广泛推荐,因为它提供了更多的加密算法,包括较新的椭圆曲线加密算法...

    cyassl-provider-0.1.zip

    总的来说,【cyassl-provider-0.1.zip】是一个与SSL相关的组件包,它提供了自定义的JCE和JSSE实现,帮助开发者在Java应用中实现更高效、更安全的SSL/TLS网络通信。通过理解和使用这个组件,开发者能够更好地控制和...

    开发环境搭建手册.doc

    开发环境是任何软件项目的基础,对于使用SPRING框架进行开发的团队来说,构建一个稳定、高效的开发环境至关重要。本手册详细介绍了如何搭建SPRING项目的开发环境,包括必要的软件安装、配置以及环境优化。 一、开发...

    FlexiProvider-1.7p7(2014)_src.zip

    Java Security Provider 是JCE的核心,它是一个接口,允许开发者实现自己的加密算法或使用第三方提供的加密算法。当我们在Java程序中使用`java.security.Security`类来访问加密服务时,实际上就是在与注册在系统中的...

    md5加密所需jar包

    描述中提到的"md5加密所需的jar包"是指为了在Java程序中使用MD5加密功能,开发者需要引入的一个外部依赖。这个jar包包含了处理MD5加密逻辑的类和方法,使得开发者无需从头编写这些底层代码,能够更便捷地实现数据的...

    Android SM2、SM3、SM4 算法支持 Service Provider 及证书制作软件包

    1、AndroidSM.jar -- SM2、SM3、SM4 算法/证书支持的 JCA/JCE Service Provider 类库 2、AndroidCRT.jar -- X.509 数字证书/PKCS#10 证书申请相关类库 3、bc422.jar -- BouncyCastle 加密库,Android 4.2.2 内置版本...

    bcpkix-jdk15on-1.49.rar

    描述中提到的问题“java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider”是一个常见的Java运行时错误,通常表示在程序运行时找不到某个类的定义。在这个特定情况下,系统无法找到...

Global site tag (gtag.js) - Google Analytics