天天看点

RSA加解密代码

从cer文件获取公钥:

private void initCer() throws Exception {
		CertificateFactory cff = CertificateFactory.getInstance("X.509");
		String filePath = Properties.getString("publickeyFilePath");
		System.out.println("cer_filePath="+filePath);
		InputStream in = new FileInputStream(filePath);
//		InputStream in = app.getBaseContext().getResources()
//				.openRawResource(R.raw.zjrcbank); // 证书文件
		Certificate cf = cff.generateCertificate(in);
		RSAPublicKey pk1 = (RSAPublicKey)cf.getPublicKey(); // 得到证书文件携带的公钥
		
		System.out.println("Public.Modulus=["+pk1.getModulus()+"]");
		System.out.println("Public.Exponent=["+pk1.getPublicExponent()+"]");
		
//		cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 定义算法:RSA
		cipher = Cipher.getInstance("RSA/ECB/NoPadding");
		cipher.init(Cipher.ENCRYPT_MODE, pk1);
	}
           

从jks文件获取私钥:

private RSAPrivateKey getPrivateFromFile() throws Exception {
		String filePath = Properties.getString("keystoreFilePath"); //hkbanking.jks
//		String filePath = Properties.getString("CSkeystoreFilePath"); //bankofchangsha.jks
		System.out.println("jks_file="+filePath);
		// String filePath = "c:/" + keystoreFilePath;
		FileInputStream fis2 = new FileInputStream(filePath);
		KeyStore ks = KeyStore.getInstance("JKS"); // 加载证书库
		char[] kspwd = storepass_hk.toCharArray(); // 证书库密码
		char[] keypwd = keypass_hk.toCharArray(); // 证书密码
		ks.load(fis2, kspwd); // 加载证书
		RSAPrivateKey pk2 = (RSAPrivateKey) ks.getKey(keyalias_hk, keypwd); // 获取证书私钥
		log("PrivateKey.Modulus=["+pk2.getModulus()+"]");
		log("PrivateKey.Exponent=["+pk2.getPrivateExponent()+"]");
		fis2.close(); 
		return pk2;
	}
           

从文本获取公钥:

public static RSAPublicKey buildRSAPublicKey(BigInteger modulus,
			BigInteger publicExponent) {
		try {
			KeyFactory kf = KeyFactory.getInstance("RSA");
			RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus,
					publicExponent);
			return (RSAPublicKey) kf.generatePublic(spec);
		} catch (Exception e) {
			throw new IllegalStateException(
					"cannot build public key by modulus and exponent", e);
		}
	}
           

从文本获取私钥:

public static RSAPrivateKey buildRSAPrivateKey(BigInteger modulus,
			BigInteger publicExponent) {
		try {
			KeyFactory kf = KeyFactory.getInstance("RSA");
			RSAPrivateKeySpec spec = new RSAPrivateKeySpec(modulus,
					publicExponent);
			return  (RSAPrivateKey)kf.generatePrivate(spec);
		} catch (Exception e) {
			throw new IllegalStateException(
					"cannot build public key by modulus and exponent", e);
		}
	}
           

用公钥初始化Cipher对象-加密:

cipher = Cipher.getInstance("RSA/ECB/NoPadding");
		cipher.init(Cipher.ENCRYPT_MODE, pk1);
           

用私钥初始化Cipher对象-解密:

Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
		cipher.init(Cipher.DECRYPT_MODE, pk2);
           

加解密:

byte[] tmp = cipher.doFinal( data );
           

其中,

1. RSA的加解密速度慢和明文数据长度有限制。

2. 在传入BigInteger的时候需要注意进制问题,pk2.getModulus(), pk2.getPrivateExponent();是十进制。但是密钥的模数和指数一般是16进制。

3. cer证书是有格式的,所以解析证书的时候需要传509格式。

4. keystore中可以存多个证书,所以需要keystore的密码;然后每个证书有别名和密码。所以JKS中传入了这是三个参数。

完。