天天看點

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中傳入了這是三個參數。

完。