小编很早之前写过一篇文章:RSA加密算法
以前封装的这一套还不错。但是缺少网络中经常要使用到的签名验签部分,所以在这里补充一下。
先晒一下总的封装:
package com.taldh;
/*
* Copyright 2013 WeCode authors
*
* Licensed under the WeCode, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License from ydonghao2@gmail.com
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import java.io.UnsupportedEncodingException;
import java.security.*;
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 java.util.HashMap;
import java.util.Map;
/**
* RSA加密组件
*
* @author ydonghao2
* @version 2.0
*/
@Slf4j
public abstract class RSACoder {
// 非对称加密算法
public static final String KEY_ALGORITHM = "RSA";
// 公钥
private static final String PUBLIC_KEY = "RSAPublicKey";
// 私钥
private static final String PRIVATE_KEY = "RSAPrivateKey";
// RSA密钥长度 2048
private static final int KEY_SIZE = 2048;
public static final String SIGNATURE_ALGORITHM = "SHA1WithRSA";
public static final String ENCODING = "utf-8";
/**
* 私钥解密
*
* @param data
* 待解密 数据
* @param key
* 私钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key)
throws Exception {
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data
* 待解密数据
* @param key
* 公钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key)
throws Exception {
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成公钥
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
*
* @param data
* 待加密数据
* @param key
* 公钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key)
throws Exception {
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥加密
*
* @param data
* 待加密 数据
* @param key
* 私钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key)
throws Exception {
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 取得私钥
*
* @param keyMap
* 密钥Map
* @return byte[] 私钥
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
public static String getBase64PrivateKey(Map<String, Object> keyMap) {
return Base64.encodeBase64String(getPrivateKey(keyMap));
}
/**
* 取得公钥
*
* @param keyMap
* 密钥Map
* @return byte[] 私钥
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
public static String getBase64PublicKey(Map<String, Object> keyMap) {
return Base64.encodeBase64String(getPublicKey(keyMap));
}
/**
* 初始化密钥
*
* @return 密钥Map
*/
public static Map<String, Object> initKey() throws Exception {
// 实例化密钥对生成器
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
// 初始化密钥对的生成
keyPairGen.initialize(KEY_SIZE);
// 生成密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 封装密钥
Map<String, Object> keyMap = new HashMap<>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私钥解密
*
* @param data
* 待解密 数据
* @param key
* 私钥
* @return byte[] 解密数据
*/
public static byte[] encryptByHexPrivateKey(byte[] data, String key)
throws Exception {
return encryptByPrivateKey(data, getKey(key));
}
/**
* 公钥加密
*
* @param data
* 待加密数据
* @param key
* 公钥
* @return byte[] 加密数据
*/
public static byte[] encryptByHexPublicKey(byte[] data, String key)
throws Exception {
return encryptByPublicKey(data, getKey(key));
}
/**
* 私钥解密
*
* @param data
* 待解密 数据
* @param key
* 私钥
* @return byte[] 解密数据
*/
public static byte[] decryptByHexPrivateKey(byte[] data, String key)
throws Exception {
return decryptByPrivateKey(data, getKey(key));
}
/**
* 公钥解密
*
* @param data
* 待解密数据
* @param key
* 公钥
* @return byte[] 解密数据
*/
public static byte[] decryptByHexPublicKey(byte[] data, String key)
throws Exception {
return decryptByPublicKey(data, getKey(key));
}
/**
* 初始化密钥
* @param keyMap 密钥Map
* @return String 16进制编码密钥
*/
public static String getHexPrivateKeyString(Map<String,Object> keyMap) throws Exception {
return Hex.encodeHexString(getPrivateKey(keyMap));
}
/**
* 初始化密钥
* @param keyMap 密钥Map
* @return String 16进制编码密钥
*/
public static String getHexPublicKeyString(Map<String , Object> keyMap) throws Exception {
return Hex.encodeHexString(getPublicKey(keyMap));
}
/**
* RSA私钥签名
*
* @param content 待签名数据
* @param privateKey 私钥
* @return 签名值
*/
public static String signByBase64PriKey(String content, byte[] privateKey) {
try {
return signByPriKey0(content, privateKey);
} catch (Exception e) {
log.error("sign error, content: {}", content, e);
}
return null;
}
/**
* RSA私钥签名
*
* @param content 待签名数据
* @param privateKey 私钥
* @return 签名值
*/
public static String signByBase64PriKey(String content, String privateKey) {
try {
byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(ENCODING));
return signByPriKey0(content, keyBytes);
} catch (Exception e) {
log.error("sign error, content: {}", content, e);
}
return null;
}
/**
* RSA私钥签名
*
* @param content 待签名数据
* @param privateKey 私钥
* @return 签名值
*/
public static String signByHexPriKey(String content, String privateKey) {
try {
return signByPriKey0(content, getKey(privateKey));
} catch (Exception e) {
log.error("sign error, content: {}", content, e);
}
return null;
}
private static String signByPriKey0(String content, byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = keyFactory.generatePrivate(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(content.getBytes(ENCODING));
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed), ENCODING);
}
/**
* 公钥验签
* @param content 签名内容
* @param sign 使用 sign 编码的pk
* @param publicKey 使用 base64 编码的pk
* @return 验签名是否成功
*/
public static boolean verifySignByBase64PublicKey(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
byte[] encodedKey = Base64.decodeBase64(publicKey.getBytes(ENCODING));
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(ENCODING));
return signature.verify(Base64.decodeBase64(sign.getBytes(ENCODING)));
} catch (Exception e) {
log.error("verify sign error, content: {}, sign: {}", content, sign, e);
}
return false;
}
/**
* 公钥验签
* @param content 签名内容
* @param sign 使用 sign 编码的pk
* @param publicKey 使用 base64 编码的pk
* @return 验签名是否成功
*/
public static boolean verifySignByHexPublicKey(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
byte[] encodedKey = Base64.decodeBase64(publicKey.getBytes(ENCODING));
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(ENCODING));
return signature.verify(Base64.decodeBase64(sign.getBytes(ENCODING)));
} catch (Exception e) {
log.error("verify sign error, content: {}, sign: {}", content, sign, e);
}
return false;
}
/**
* 公钥验签
* @param content 签名内容
* @param sign 使用 sign 编码的pk
* @param publicKey 未使用base64位编码的pk
* @return 验签名是否成功
*/
public static boolean verifySignByPublicKey(String content, String sign, byte[] publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(ENCODING));
return signature.verify(Base64.decodeBase64(sign.getBytes(ENCODING)));
} catch (Exception e) {
log.error("verify sign error, content: {}, sign: {}", content, sign, e);
}
return false;
}
private static byte[] getKey(String key) throws Exception {
return Hex.decodeHex(key.toCharArray());
}
}
RSA加密解密不在这里详述。理论上的RSA是一个公钥一个私钥的,不考虑一个私钥,多个公钥的变种。
上面撸的代码虽然很长,但是内容其实没那么多。
首先是生成密钥(这里把类设计成抽象类就是为了防止有人对这个类做初始化。)
/**
* 初始化密钥
*
* @return 密钥Map
*/
public static Map<String, Object> initKey() throws Exception {
// 实例化密钥对生成器
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
// 初始化密钥对的生成
keyPairGen.initialize(KEY_SIZE);
// 生成密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 封装密钥
Map<String, Object> keyMap = new HashMap<>(2);
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
然后以encrypt 开头的方法都是加密方法。以decrypt 开头的都是解密方法。
方法中包含Base64的都是将公钥私钥做了Base64编码对外交互的。
方法中包含Hex的都是将公钥私钥做了16进制编码对外交互的。(储存密钥或者网络交互的时候推荐使用这种方式。)
签名及验签
签名及验签是为了防止黑客篡改网络中的机器交互的内容。其实RSA加密和解密就能解决这个问题,但是加密解密的效率很低,特别是加密解密的内容特别多的时候,这个时候就需要做一个折中(计算机世界很擅长折中。)
签名即选一批内容出来加密,并不是所有东西加密。签名是使用了摘要算法之后再进行加密的,解密的时候使用相同的摘要算法解密。不丢书包了,直接看看签名和验签的方法。
private static String signByPriKey0(String content, byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey priKey = keyFactory.generatePrivate(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(content.getBytes(ENCODING));
byte[] signed = signature.sign();
return new String(Base64.encodeBase64(signed), ENCODING);
}
/**
* 公钥验签
* @param content 签名内容
* @param sign 使用 sign 编码的pk
* @param publicKey 未使用base64位编码的pk
* @return 验签名是否成功
*/
public static boolean verifySignByPublicKey(String content, String sign, byte[] publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKey));
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(content.getBytes(ENCODING));
return signature.verify(Base64.decodeBase64(sign.getBytes(ENCODING)));
} catch (Exception e) {
log.error("verify sign error, content: {}, sign: {}", content, sign, e);
}
return false;
}
最重要的是调用了java.security.Signature类的签名。
使用例子如下:
public static void main(String[] args) throws Exception {
// 初始化密钥
Map<String, Object> keyMap = RSACoder.initKey();
byte[] publicKey = RSACoder.getPublicKey(keyMap);
byte[] privateKey = RSACoder.getPrivateKey(keyMap);
System.err.println("公钥:\t" + Base64.encodeBase64String(publicKey));
System.err.println("公钥:\t" + RSACoder.getHexPublicKeyString(keyMap));
System.err.println("公钥:\t" + publicKey.toString());
System.err.println("私钥:\t" + Base64.encodeBase64String(privateKey));
System.err.println("私钥:\t" + RSACoder.getHexPrivateKeyString(keyMap));
System.err.println("公钥:\t" + privateKey.toString());
System.err.println("---私钥加密----公钥解密----");
String inputStr1 = "asdfasdf1234SDFafdsfsdfsdfaw2341sdgsdfg";
byte[] data1 = inputStr1.getBytes();
System.err.println("原文:\t" + inputStr1);
// 加密
byte[] encodedData1 = RSACoder.encryptByPrivateKey(data1, privateKey);
System.err.println("加密后:\t" + Base64.encodeBase64String(encodedData1));
// 解密
byte[] decodedData1 = RSACoder.decryptByPublicKey(encodedData1,
publicKey);
String outputStr1 = new String(decodedData1);
System.err.println("解密后:\t" + outputStr1);
System.out.println("签名");
final String content = "asdfasdf";
final String sign = RSACoder.signByBase64PriKey(inputStr1, privateKey);
System.out.println("sign:"+sign);
System.out.println("验签");
System.out.println(RSACoder.verifySignByPublicKey(inputStr1, sign, publicKey));
// 校验
// Assert.assertEquals(inputStr1, outputStr1);
}
运行效果如下:
公钥: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm4KXGBnIdCBJM/B2oVvBi7S63X4axG24psyYGnVkOZMTDinvhWmCygeMSu27o+EB6bftGnwCT6SgNkG5XRTPg7stWuUiWUArKAmLWcXjt3SvpbNxPjWgD8TOrtjkQDX8Xtt2DHe9Uj+WZSQHENViivFB9+iB8ib+bb7H0dsmofcNdC5P22NhhumQJ+Yipn2VPwLZUgegJwlXynFs15qPLkKMhp0HxpF+Rzg++0OpFOi8YVSduUM2V9fCevtF/vE40uU0QvWXv/dx4RIUE2avtHTdboLWMd8pX8I8pkcL0PeEjrdJSxgKw0d2aPXpLXGcgqYIA15togr9CoVRNtDBpQIDAQAB
公钥: 30820122300d06092a864886f70d01010105000382010f003082010a02820101009b82971819c874204933f076a15bc18bb4badd7e1ac46db8a6cc981a75643993130e29ef856982ca078c4aedbba3e101e9b7ed1a7c024fa4a03641b95d14cf83bb2d5ae52259402b28098b59c5e3b774afa5b3713e35a00fc4ceaed8e44035fc5edb760c77bd523f9665240710d5628af141f7e881f226fe6dbec7d1db26a1f70d742e4fdb636186e99027e622a67d953f02d95207a0270957ca716cd79a8f2e428c869d07c6917e47383efb43a914e8bc61549db9433657d7c27afb45fef138d2e53442f597bff771e112141366afb474dd6e82d631df295fc23ca6470bd0f7848eb7494b180ac3477668f5e92d719c82a608035e6da20afd0a855136d0c1a50203010001
公钥: [B@120d6fe6
私钥: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCbgpcYGch0IEkz8HahW8GLtLrdfhrEbbimzJgadWQ5kxMOKe+FaYLKB4xK7buj4QHpt+0afAJPpKA2QbldFM+Duy1a5SJZQCsoCYtZxeO3dK+ls3E+NaAPxM6u2ORANfxe23YMd71SP5ZlJAcQ1WKK8UH36IHyJv5tvsfR2yah9w10Lk/bY2GG6ZAn5iKmfZU/AtlSB6AnCVfKcWzXmo8uQoyGnQfGkX5HOD77Q6kU6LxhVJ25QzZX18J6+0X+8TjS5TRC9Ze/93HhEhQTZq+0dN1ugtYx3ylfwjymRwvQ94SOt0lLGArDR3Zo9ektcZyCpggDXm2iCv0KhVE20MGlAgMBAAECggEAOyQjCktj7KYKsPIWa69VoCgPmQTIcUO5IdZVUlqqzyqb6JsSOI6z6tmMBUL8RYrhC12jkpru1hMpyvib4kZz1Qluak8SDRdWUleu42la/P4nfsELpDkIsnaKk/xwcesWG40jDALNwWXlcHmPJlvAqk6uY/XM1ab2xA32OF08CAQvr0eOYFHsx1RsISO8e/4PPW903jxAXiJuqV/i/vSrRp5ej4XU+A0lRqxZjfh5LuFBMNnLRc/NJb1gqheqK6VQtTdRKqv5rgejZZykOQn5m4fZnG3gY/yXw8dGHVIjoKb9g3awdj4REXh2g1CAJlV0ISv8GlOQWn9nTgbley/0AQKBgQDkug2/2Jp9zxK3j8fXsCqZCKCG6qiOSlyoyncxV+YK2GZpDAAP4y2GeddqzN0D7/8XZ1nuNSbs5XLwErWLoHXaLRkVkhLobmiCG/F+lY35sIeJ+p5qnh2g5ZZe/uxcgWqUiGXa+oxKbfcMjwZ2ca3viZGKPOQOANFowcm5qTit5QKBgQCuDZQThmBmO2F42bDzAJG6z3rTbx/6S71GEjFn12I99trPz4gXliERcOunAU9b0HVKkW242Kw3zjvV56xa+h3l34V4cOeSASRD+zHSHZpmLALNObioCPYKy3J4qTNQ0/C158o4pe94r5pd0NMa5+oGDyQ2tz0rrWN3ohxkoKSIwQKBgGqMJRWGUElk6eIqjzxxaxaIx0ayDzzhdRKH5khNGvNYZTRwC6Na/30SSwAMWLSZ2unLEkB98BkQtZ8SCBH3+I5ezb2Xo0k1DWf2nmOKRW3YBvuGjL870q9947Ny6yYYf06bz17XsfyGBzyJb8hDInRgUDTmMpI3XVWAWHktVCLlAoGAdPVs5r3qs2f9tN7b+D8OrnDTwZav71rL4nVBO91RCACEwxZbBjZ9HCI8SGop8LGgz63wBEGdYJa2QKRAfpYKVzkfkHKWOdeIjiITNXVtFnFGpK+/9TKoW1KhJpHUiOESpLoQeoaO6BNgcOBtq2viJ5YvKJFzipEmAPMvjzMfvUECgYAK3t0VtyGf7dzXUP0xddkMoPpPstBUWWFpPEjU5vZ+LslvDnCD8f0SUBANmfOOPDb2Szne7uhXYxJRZ2ZSpmXzMrpUQABCxGkbP1QXW7EAiVWGWbPm48itXNojRESRf+Q6WAXud1NgqmnqamhnZHCmnXmUC/CywPJAo4GG7AJJew==
私钥: 308204bc020100300d06092a864886f70d0101010500048204a6308204a202010002820101009b82971819c874204933f076a15bc18bb4badd7e1ac46db8a6cc981a75643993130e29ef856982ca078c4aedbba3e101e9b7ed1a7c024fa4a03641b95d14cf83bb2d5ae52259402b28098b59c5e3b774afa5b3713e35a00fc4ceaed8e44035fc5edb760c77bd523f9665240710d5628af141f7e881f226fe6dbec7d1db26a1f70d742e4fdb636186e99027e622a67d953f02d95207a0270957ca716cd79a8f2e428c869d07c6917e47383efb43a914e8bc61549db9433657d7c27afb45fef138d2e53442f597bff771e112141366afb474dd6e82d631df295fc23ca6470bd0f7848eb7494b180ac3477668f5e92d719c82a608035e6da20afd0a855136d0c1a50203010001028201003b24230a4b63eca60ab0f2166baf55a0280f9904c87143b921d655525aaacf2a9be89b12388eb3ead98c0542fc458ae10b5da3929aeed61329caf89be24673d5096e6a4f120d17565257aee3695afcfe277ec10ba43908b2768a93fc7071eb161b8d230c02cdc165e570798f265bc0aa4eae63f5ccd5a6f6c40df6385d3c08042faf478e6051ecc7546c2123bc7bfe0f3d6f74de3c405e226ea95fe2fef4ab469e5e8f85d4f80d2546ac598df8792ee14130d9cb45cfcd25bd60aa17aa2ba550b537512aabf9ae07a3659ca43909f99b87d99c6de063fc97c3c7461d5223a0a6fd8376b0763e11117876835080265574212bfc1a53905a7f674e06e57b2ff40102818100e4ba0dbfd89a7dcf12b78fc7d7b02a9908a086eaa88e4a5ca8ca773157e60ad866690c000fe32d8679d76accdd03efff176759ee3526ece572f012b58ba075da2d19159212e86e68821bf17e958df9b08789fa9e6a9e1da0e5965efeec5c816a948865dafa8c4a6df70c8f067671adef89918a3ce40e00d168c1c9b9a938ade502818100ae0d94138660663b6178d9b0f30091bacf7ad36f1ffa4bbd46123167d7623df6dacfcf881796211170eba7014f5bd0754a916db8d8ac37ce3bd5e7ac5afa1de5df857870e792012443fb31d21d9a662c02cd39b8a808f60acb7278a93350d3f0b5e7ca38a5ef78af9a5dd0d31ae7ea060f2436b73d2bad6377a21c64a0a488c10281806a8c251586504964e9e22a8f3c716b1688c746b20f3ce1751287e6484d1af3586534700ba35aff7d124b000c58b499dae9cb12407df01910b59f120811f7f88e5ecdbd97a349350d67f69e638a456dd806fb868cbf3bd2af7de3b372eb26187f4e9bcf5ed7b1fc86073c896fc8432274605034e63292375d558058792d5422e502818074f56ce6bdeab367fdb4dedbf83f0eae70d3c196afef5acbe275413bdd51080084c3165b06367d1c223c486a29f0b1a0cfadf004419d6096b640a4407e960a57391f90729639d7888e221335756d167146a4afbff532a85b52a12691d488e112a4ba107a868ee8136070e06dab6be227962f2891738a912600f32f8f331fbd410281800adedd15b7219feddcd750fd3175d90ca0fa4fb2d0545961693c48d4e6f67e2ec96f0e7083f1fd1250100d99f38e3c36f64b39deeee857631251676652a665f332ba54400042c4691b3f54175bb10089558659b3e6e3c8ad5cda234444917fe43a5805ee775360aa69ea6a68676470a69d79940bf0b2c0f240a38186ec02497b
公钥: [B@4ba2ca36
---私钥加密----公钥解密----
原文: asdfasdf1234SDFafdsfsdfsdfaw2341sdgsdfg
加密后: RT8qtZjoHNmpxm5A2nahKrGTBoSLOr6p3hwX6vvRRvkZIP9nnQkhHZ3yttMhS/SyVLeBQricSxgsf2EGx2EfH+Oh83XtJHX6TNa/v3c8uljO47SncYoGgZhnREIWOp9bgE6yDTvZuSxHTpJdupRpbKUsFAaL1um8SYnYAxiNvmpUXVz9D+wLNN2wXM15E3ivJwrFWfLFDOrGLkkqWwp+1k6dL5v7qTMccgYHm7UgHn9LmET892sRsryBR3W/t4TTCS7TmbaaUkVU13e0HDxC2vYi6PQguD/T7UaxulAV8Icx3J8C1jgefKQu7zewhOgEleDyAwHbj39vPhnHPfAizQ==
解密后: asdfasdf1234SDFafdsfsdfsdfaw2341sdgsdfg
签名
sign:YsUDOHxt0/mKkMTkyAYb1xot4INCRC9yKO1ukt58+KzOl3h/31LjHSaTV6i7MY6cSvxVNnW8gV21l3BXJj0P1M5MZhFVl76tWWxTYIvOro9l1MBSbK+S+CA5nRLMLtq9c/HhFI91m9355WZUsJ/6JMpM+PpnBXwhoO2TdVNcXTTxTKEAhHfRnZEOQO3lfTHijDzl0Yte7Nx4DVD+iweXO2s7CygXcnQbHXSt46JGMa3AV+DeIZ9v+f3aG1crprU6HjLk4AnmJa0FuD+L5adnLLuiFlEHzoYghXRLrmmz/4Ay69vLVJ4AEuDqFS1uRu5dYlDpxeTdq91NB/oZiL12dg==
验签
true
读者也可以自己参数做16进制(Hex)编码。