RSA非对称密钥加解密使用示例
来源:互联网 发布:github php开源项目 编辑:程序博客网 时间:2024/05/17 04:48
一、简介:
RSA加密算法是最常用的非对称加密算法,CFCA在证书服务中离不了它。RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。
二、RSA的公钥、私钥的组成,以及加密、解密的公式
三、使用方式:
① 假设A、B机器进行通信,已A机器为主;
② A首先需要用自己的私钥为发送请求数据签名,并将公钥一同发送给B;
③ B收到数据后,需要用A发送的公钥进行验证,已确保收到的数据是未经篡改的;
④ B验签通过后,处理逻辑,并把处理结果返回,返回数据需要用A发送的公钥进行加密(公钥加密后,只能用配对的私钥解密);
⑤ A收到B返回的数据,使用私钥解密,至此,一次数据交互完成。
四、代码示例:
1、第一步获取私钥,为签名做准备。
/** * 读取私钥 返回PrivateKey * @param path 包含私钥的证书路径 * @param password 私钥证书密码 * @return 返回私钥PrivateKey * @throws KeyStoreException * @throws NoSuchAlgorithmException * @throws CertificateException * @throws IOException * @throws UnrecoverableKeyException */ private static PrivateKey getPrivateKey(String path,String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException { KeyStore ks = KeyStore.getInstance("PKCS12"); FileInputStream fis = new FileInputStream(path); char[] nPassword = null; if ((password == null) || password.trim().equals("")) { nPassword = null; } else { nPassword = password.toCharArray(); } ks.load(fis, nPassword); fis.close(); Enumeration<String> en = ks.aliases(); String keyAlias = null; if (en.hasMoreElements()) { keyAlias = (String) en.nextElement(); } return (PrivateKey) ks.getKey(keyAlias, nPassword); }
2、签名示例:通过第一步得到的私钥,进行签名操作,具体请看以下代码:
/** * 私钥签名: 签名方法如下:BASE64(RSA(MD5(src),privatekey)),其中src为需要签名的字符串,privatekey是商户的CFCA证书私钥。 * @param plainText 待签名字符串 * @param path 签名私钥路径 * @param password 签名私钥密码 * @return 返回签名后的字符串 * @throws Exception */ public static String sign(String plainText,String path,String password) throws Exception { /* * MD5加密 */ MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(plainText.getBytes("utf-8")); byte[] digestBytes = md5.digest(); /* * 用私钥进行签名 RSA * Cipher负责完成加密或解密工作,基于RSA */ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); //ENCRYPT_MODE表示为加密模式 cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(path, password)); //加密 byte[] rsaBytes = cipher.doFinal(digestBytes); //Base64编码 return Base64.byteArrayToBase64(rsaBytes);
3、B收到数据后,需要使用A提供的公钥信息进行验签,此处使用公钥的N、E进行验签首先通过公钥N、E得到公钥PublicKey,如下:
/** * 根据公钥n、e生成公钥 * @param modulus 公钥n串 * @param publicExponent 公钥e串 * @return 返回公钥PublicKey * @throws Exception */ public static PublicKey getPublickKey(String modulus, String publicExponent) throws Exception { KeySpec publicKeySpec = new RSAPublicKeySpec( new BigInteger(modulus, 16), new BigInteger(publicExponent, 16)); KeyFactory factory = KeyFactory.getInstance("RSA"); PublicKey publicKey = factory.generatePublic(publicKeySpec); return publicKey; }
得到公钥PublicKey后,再去验证签名,代码如下:
/** * 用公钥证书进行验签 * @param message 签名之前的原文 * @param cipherText 签名 * @param pubKeyn 公钥n串 * @param pubKeye 公钥e串 * @return boolean 验签成功为true,失败为false * @throws Exception */ public static boolean verify(String message, String cipherText,String pubKeyn, String pubKeye) throws Exception { Cipher c4 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示解密模式 c4.init(Cipher.DECRYPT_MODE, getPublickKey(pubKeyn,pubKeye)); // 解密 byte[] desDecTextBytes = c4.doFinal(Base64.base64ToByteArray(cipherText)); // 得到前置对原文进行的MD5 String md5Digest1 = Base64.byteArrayToBase64(desDecTextBytes); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(message.getBytes("utf-8")); byte[] digestBytes = md5.digest(); // 得到商户对原文进行的MD5 String md5Digest2 = Base64.byteArrayToBase64(digestBytes); // 验证签名 if (md5Digest1.equals(md5Digest2)) { return true; } else { return false; } }
至此,签名验签已经完毕
4、提供一个从.cer文件读取公钥的方法:
/** * 读取公钥cer * @param path .cer文件的路径 如:c:/abc.cer * @return base64后的公钥串 * @throws IOException * @throws CertificateException */ public static String getPublicKey(String path) throws IOException, CertificateException{ InputStream inStream = new FileInputStream(path); ByteArrayOutputStream out = new ByteArrayOutputStream(); int ch; String res = ""; while ((ch = inStream.read()) != -1) { out.write(ch); } byte[] result = out.toByteArray(); res = Base64.byteArrayToBase64(result); return res; }
代码封装
package utils;import java.io.ByteArrayOutputStream;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import java.security.Signature;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.HashMap;import java.util.Map;import javax.crypto.Cipher;/** * <p> * RSA公钥/私钥/签名工具包 * </p> * <p> * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) * </p> * <p> * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/> * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 * </p> * * @author IceWee * @date 2012-4-26 * @version 1.0 */public class RSAUtils { /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPublicKey"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * <p> * 生成密钥对(公钥和私钥) * </p> * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64Utils.encode(signature.sign()); } /** * <p> * 校验数字签名 * </p> * * @param data * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64Utils.decode(sign)); } /** * <P> * 私钥解密 * </p> * * @param encryptedData * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * <p> * 公钥解密 * </p> * * @param encryptedData * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher .doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher .doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** * <p> * 公钥加密 * </p> * * @param data * 源数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * <p> * 私钥加密 * </p> * * @param data * 源数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** * <p> * 获取私钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64Utils.encode(key.getEncoded()); } /** * <p> * 获取公钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); }}
Base64Utils文件
package utils;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import com.sun.org.apache.xml.internal.security.utils.Base64; /** * <p> * BASE64编码解码工具包 * </p> * <p> * 依赖javabase64-1.3.1.jar * </p> * * @author IceWee * @date 2012-5-19 * @version 1.0 */public class Base64Utils { /** * 文件读取缓冲区大小 */ private static final int CACHE_SIZE = 1024; /** * <p> * BASE64字符串解码为二进制数据 * </p> * * @param base64 * @return * @throws Exception */ public static byte[] decode(String base64) throws Exception { return Base64.decode(base64.getBytes()); } /** * <p> * 二进制数据编码为BASE64字符串 * </p> * * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { return new String(Base64.encode(bytes)); } /** * <p> * 将文件编码为BASE64字符串 * </p> * <p> * 大文件慎用,可能会导致内存溢出 * </p> * * @param filePath 文件绝对路径 * @return * @throws Exception */ public static String encodeFile(String filePath) throws Exception { byte[] bytes = fileToByte(filePath); return encode(bytes); } /** * <p> * BASE64字符串转回文件 * </p> * * @param filePath 文件绝对路径 * @param base64 编码字符串 * @throws Exception */ public static void decodeToFile(String filePath, String base64) throws Exception { byte[] bytes = decode(base64); byteArrayToFile(bytes, filePath); } /** * <p> * 文件转换为二进制数组 * </p> * * @param filePath 文件路径 * @return * @throws Exception */ public static byte[] fileToByte(String filePath) throws Exception { byte[] data = new byte[0]; File file = new File(filePath); if (file.exists()) { FileInputStream in = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream(2048); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); in.close(); data = out.toByteArray(); } return data; } /** * <p> * 二进制数据写文件 * </p> * * @param bytes 二进制数据 * @param filePath 文件生成目录 */ public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception { InputStream in = new ByteArrayInputStream(bytes); File destFile = new File(filePath); if (!destFile.getParentFile().exists()) { destFile.getParentFile().mkdirs(); } destFile.createNewFile(); OutputStream out = new FileOutputStream(destFile); byte[] cache = new byte[CACHE_SIZE]; int nRead = 0; while ((nRead = in.read(cache)) != -1) { out.write(cache, 0, nRead); out.flush(); } out.close(); in.close(); }}
测试用例:
package util;import java.util.Map;import RSAUtils;public class RSATester { static String publicKey; static String privateKey; static { try { Map<String, Object> keyMap = RSAUtils.genKeyPair(); publicKey = RSAUtils.getPublicKey(keyMap); privateKey = RSAUtils.getPrivateKey(keyMap); System.err.println("公钥: \n\r" + publicKey); System.err.println("私钥: \n\r" + privateKey); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { test(); testSign(); } static void test() throws Exception { System.err.println("公钥加密——私钥解密"); String source = "这是一行没有任何意义的文字,你看完了等于没看,不是吗?"; System.out.println("\r加密前文字:\r\n" + source); byte[] data = source.getBytes(); byte[] encodedData = RSAUtils.encryptByPublicKey(data, publicKey); System.out.println("加密后文字:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey); String target = new String(decodedData); System.out.println("解密后文字: \r\n" + target); } static void testSign() throws Exception { System.err.println("私钥加密——公钥解密"); String source = "这是一行测试RSA数字签名的无意义文字"; System.out.println("原文字:\r\n" + source); byte[] data = source.getBytes(); byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey); System.out.println("加密后:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey); String target = new String(decodedData); System.out.println("解密后: \r\n" + target); System.err.println("私钥签名——公钥验证签名"); String sign = RSAUtils.sign(encodedData, privateKey); System.err.println("签名:\r" + sign); boolean status = RSAUtils.verify(encodedData, publicKey, sign); System.err.println("验证结果:\r" + status); }}
生成RSA密钥、保存到文件、从文件读取、加密、解密等操作
import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class RSATest { public static void main(String[] args) { try { RSATest encrypt = new RSATest(); String encryptText = "encryptText"; // Generate keys KeyPair keyPair = encrypt.generateKey(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); byte[] e = encrypt.encrypt(publicKey, encryptText.getBytes()); byte[] de = encrypt.decrypt(privateKey, e); System.out.println(toHexString(e)); System.out.println(toHexString(de)); } catch (Exception e) { e.printStackTrace(); } } public KeyPair generateKey() throws NoSuchAlgorithmException { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(1024, new SecureRandom()); KeyPair keyPair = keyPairGen.generateKeyPair(); return keyPair; } public void saveKey(KeyPair keyPair, String publicKeyFile, String privateKeyFile) throws ConfigurationException { PublicKey pubkey = keyPair.getPublic(); PrivateKey prikey = keyPair.getPrivate(); // save public key PropertiesConfiguration publicConfig = new PropertiesConfiguration( publicKeyFile); publicConfig.setProperty("PULIICKEY", toHexString(pubkey.getEncoded())); publicConfig.save(); // save private key PropertiesConfiguration privateConfig = new PropertiesConfiguration( privateKeyFile); privateConfig.setProperty("PRIVATEKEY", toHexString(prikey.getEncoded())); privateConfig.save(); } /** * @param filename * @param type: * 1-public 0-private * @return * @throws ConfigurationException * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public Key loadKey(String filename, int type) throws ConfigurationException, NoSuchAlgorithmException, InvalidKeySpecException { PropertiesConfiguration config = new PropertiesConfiguration(filename); KeyFactory keyFactory = KeyFactory.getInstance("RSA", new BouncyCastleProvider()); if (type == 0) { // privateKey String privateKeyValue = config.getString("PULIICKEY"); PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( toBytes(privateKeyValue)); PrivateKey privateKey = keyFactory.generatePrivate(priPKCS8); return privateKey; } else { // publicKey String privateKeyValue = config.getString("PRIVATEKEY"); X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec( toBytes(privateKeyValue)); PublicKey publicKey = keyFactory.generatePublic(bobPubKeySpec); return publicKey; } } /** * Encrypt String. * * @return byte[] */ protected byte[] encrypt(RSAPublicKey publicKey, byte[] data) { if (publicKey != null) { try { Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); } } return null; } /** * Basic decrypt method * * @return byte[] */ protected byte[] decrypt(RSAPrivateKey privateKey, byte[] raw) { if (privateKey != null) { try { Cipher cipher = Cipher.getInstance("RSA", new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(raw); } catch (Exception e) { e.printStackTrace(); } } return null; } public static String toHexString(byte[] b) { StringBuilder sb = new StringBuilder(b.length * 2); for (int i = 0; i < b.length; i++) { sb.append(HEXCHAR[(b[i] & 0xf0) >>> 4]); sb.append(HEXCHAR[b[i] & 0x0f]); } return sb.toString(); } public static final byte[] toBytes(String s) { byte[] bytes; bytes = new byte[s.length() / 2]; for (int i = 0; i < bytes.length; i++) { bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2), 16); } return bytes; } private static char[] HEXCHAR = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; }
推荐阅读
阅读全文
0 0
- Java中RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用示例
- RSA非对称密钥加解密使用示例
- Java中RSA非对称密钥加解密使用
- Android 使用RSA 非对称加解密
- 非对称加解密(RSA)
- RSA 非对称加解密
- RSA非对称加解密
- RSA非对称加解密算法的使用
- C#RSA非对称加解密
- 非对称加解密基础 - RSA算法
- openssl RSA 非对称加解密
- RSA 非对称加解密算法
- iOS RSA非对称加解密
- HIVE CREATE TABLE(一)
- python--为什么Python有相同的不可变对象id不同?
- 变量的生命周期和{ }的相关知识
- Win10 中VS2015 配置opencv3.2
- 数据结构与算法-伸展树
- RSA非对称密钥加解密使用示例
- 泛微OA节点执行接口实现
- KFC系列之
- spring kafka源码解读
- 对C#Chart控件使用整理
- 如何在Vue 2中处理文件上传
- 史上最详细最容易理解的HMM文章
- redis高并发抽奖
- 理论篇:数据库分库分表的基本思想和切分策略