最近工作需求,需要對接第三方廠家的二維碼,大體流程是對方提供密鑰對,然後我這邊将參數 簽名、加密後去請求對方接口,拿到文檔之後大體看了一下,就尋思? 哦RSA啊 簡單!我之前寫過工具類,直接用就完事。。。。 結果。。。。 異常報錯資訊
java.security.InvalidKeyException: IOException : algid parse error, not a sequence
這裡報錯原因也查了好久,百思不得其解??? 最後沒辦法與對方技術拉群進行讨論,然後得知對方是用C#生成的密鑰對。 what!!? 這裡然後想到是不是因為Java和C#加解密有差別? 大概查閱了一下資料,得出結論 C#生成的密鑰對是PKCS1而 Java内部簽名方法隻能使用PKCS8 如何解決?廢話不說 直接上簽名、驗簽、加解密代碼 需要的第三方工具maven依賴
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.1</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
簽名驗簽
import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* RSA簽名驗簽類
*/
public class RSASignaturePKCS1 {
/**
* RSA簽名
*
* @param content 待簽名資料
* @param privateKey 商戶私鑰
* @param encode 字元集編碼
* @return 簽名值
*/
public static String sign(String content, String privateKey, String encode) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Decoder.decode(privateKey));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes(encode));
byte[] signed = signature.sign();
return Base64Encoder.encode(signed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 簽名算法
*/
public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
public static String sign(String content, String privateKey) {
try {
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Decoder.decode(privateKey));
KeyFactory keyf = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyf.generatePrivate(priPKCS8);
Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(priKey);
signature.update(content.getBytes("utf-8"));
byte[] signed = signature.sign();
//Log.i("111111---", "----"+bytesToHexString(signed));
return bytesToHexString(signed);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
}
/**
* RSA驗簽名檢查
*
* @param content 待簽名資料
* @param sign 簽名值
* @param publicKey 配置設定給開發商公鑰
* @param encode 字元集編碼
* @return 布爾值
*/
public static boolean doCheck(String content, String sign, String publicKey, String encode) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Decoder.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes(encode));
boolean bverify = signature.verify(Base64Decoder.decode(sign));
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean doCheck(String content, String sign, String publicKey) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64Decoder.decode(publicKey);
PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
Signature signature = Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(pubKey);
signature.update(content.getBytes());
boolean bverify = signature.verify(Base64Decoder.decode(sign));
return bverify;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static String signWhole(String keycode, String param) throws InvalidKeySpecException {
// 使用私鑰加簽
byte[] signature = null;
try {
//擷取privatekey
byte[] keyByte = Base64Decoder.decode(keycode);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encoderule = new PKCS8EncodedKeySpec(keyByte);
PrivateKey privatekey = keyfactory.generatePrivate(encoderule);
//用私鑰給入參加簽
Signature sign = Signature.getInstance("SHA1WithRSA");
sign.initSign(privatekey);
sign.update(param.getBytes());
signature = sign.sign();
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeyException e) {
e.printStackTrace();
}
//将加簽後的入參轉成16進制
String terminal = Hex.encodeHexString(signature);
return Base64Encoder.encode(signature);
}
public static String sign1(String in, PrivateKey privateKey) throws Exception {
Signature signa = Signature.getInstance("SHA1WithRSA");
//Signature signa = Signature.getInstance("MD5WithRSA");
signa.initSign(privateKey);
signa.update(in.getBytes());
byte[] signdata = signa.sign();
return org.apache.commons.codec.binary.Base64.encodeBase64String(signdata);
}
/*
* SHA1WithRSA驗簽
*/
public static boolean isValid1(String in, String signData, PublicKey publicKey) throws Exception {
Signature signa = Signature.getInstance("SHA1WithRSA");
//Signature signa = Signature.getInstance("MD5WithRSA");
signa.initVerify(publicKey);
signa.update(in.getBytes());
byte[] sign_byte = org.apache.commons.codec.binary.Base64.decodeBase64(signData);
boolean flag = signa.verify(sign_byte);
return flag;
}
public static boolean verifyWhole(String param, String signature, String keycode) {
try {
//擷取公鑰
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] keyByte = cn.hutool.core.codec.Base64.decode(keycode);
X509EncodedKeySpec encodeRule = new X509EncodedKeySpec(keyByte);
PublicKey publicKey = keyFactory.generatePublic(encodeRule);
//用擷取到的公鑰對 入參中未加簽參數param 與 入參中的加簽之後的參數signature 進行驗簽
Signature sign = Signature.getInstance("SHA1WithRSA");
sign.initVerify(publicKey);
sign.update(param.getBytes());
//将16進制碼轉成字元數組
byte[] hexByte = hexStringToBytes(signature);
//驗證簽名
return sign.verify(hexByte);
} catch (NoSuchAlgorithmException | SignatureException | InvalidKeySpecException | InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
/**
* 将Hex String轉換為Byte數組
*
* @param hexString the hex string
* @return the byte [ ]
*/
public static byte[] hexStringToBytes(String hexString) {
if (StringUtils.isEmpty(hexString)) {
return null;
}
hexString = hexString.toLowerCase();
final byte[] byteArray = new byte[hexString.length() >> 1];
int index = 0;
for (int i = 0; i < hexString.length(); i++) {
if (index > hexString.length() - 1) {
return byteArray;
}
byte highDit = (byte) (Character.digit(hexString.charAt(index), 16) & 0xFF);
byte lowDit = (byte) (Character.digit(hexString.charAt(index + 1), 16) & 0xFF);
byteArray[i] = (byte) (highDit << 4 | lowDit);
index += 2;
}
return byteArray;
}
public static void main(String[] args) throws Exception {
String privateKey = "MIIBOwIBAAJBANKryRATx3iBDQNZR0NvA3UGTLxDaGf0DDQQ4/wECfbEbXGWKKDq\n" +
"iOKeWvIBJ+yRc1a+Mm2no8CU2GMnid+s2aECAwEAAQJAP/Z8U29N7t5vzwZ6RpUc\n" +
"HZnODpMAzh8g3WYLcmbfh5ZLBlC7cK7deXpCNN99RM8q+h0cL/jrTfyMQjbRva92\n" +
"iQIhAOnWOVpsysKyr5N2h8q1zvzF1eNxnL+A+CwGu10/7zWrAiEA5qN4kpeFGgp4\n" +
"s+LkTSDHj4jaOswd4/rB03Zy3XFHyeMCIQDfIRPJPVadQnRXehtJSwMgIIdgaODx\n" +
"u9cT67iN2pwf0QIhAIbm5PZxc+P4bgNh2gGXA8Lb3DF6BJ29pTOH28XUpZXbAiA4\n" +
"Fq4J9sOPQdN8wLBHqO8sFz4jZUe8mRZdlBvfNurUUA==";
String publicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANKryRATx3iBDQNZR0NvA3UGTLxDaGf0\n" +
"DDQQ4/wECfbEbXGWKKDqiOKeWvIBJ+yRc1a+Mm2no8CU2GMnid+s2aECAwEAAQ==";
String pkcs8 = RsaPkcsTransformer.formatPkcs1ToPkcs8(privateKey);
System.out.println(pkcs8);
System.out.println("============================================");
Map<String, Object> map = new LinkedHashMap<>(2);
Map<String, Object> requestMap = new LinkedHashMap<>(6);
requestMap.put("EqId", "123");
requestMap.put("time", "2019-04-01 15:00:06");
requestMap.put("SysVer", "");
map.put("app_key", "pub");
map.put("format", "json");
map.put("request", JSONObject.toJSONString(requestMap));
map.put("method", "Heart");
map.put("sign_method", "rsa");
StringBuilder builder = new StringBuilder();
map.forEach((k, v) -> builder.append(k).append(v));
System.out.println(builder.toString());
System.out.println("===================== 拼裝資料 =======================");
// 生成PrivateKey(前提對PKCS1變換為PKCS8)
byte[] keyByte = cn.hutool.core.codec.Base64.decode(pkcs8);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodeRule = new PKCS8EncodedKeySpec(keyByte);
PrivateKey privatekey = keyfactory.generatePrivate(encodeRule);
System.out.println("===================== 簽名傳回 =======================");
String pri = sign1(builder.toString(), privatekey);
System.out.println(pri);
//擷取privatekey
System.out.println("===================== 驗簽傳回 =======================");
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] pubKeyByte = cn.hutool.core.codec.Base64.decode(publicKey);
X509EncodedKeySpec pubEncodeRule = new X509EncodedKeySpec(pubKeyByte);
PublicKey pubKey = keyFactory.generatePublic(pubEncodeRule);
System.out.println(isValid1(builder.toString(), pri, pubKey));
// System.out.println(verifyWhole(str, pri, publicKey));
// DigitalSignatureHelper.sign(str,)
}
}
PKCS#1 轉 PKCS#8
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import java.io.StringWriter;
public class RsaPkcsTransformer {
// private static final String COMMENT_BEGIN_FLAG = "-----";
// private static final String RETURN_FLAG_R = "\r";
// private static final String RETURN_FLAG_N = "\n";
//format PKCS#8 to PKCS#1
public static String formatPkcs8ToPkcs1(String rawKey) throws Exception {
String result = null;
//extract valid key content
String validKey = rawKey;//RsaPemUtil.extractFromPem(rawKey); // pem檔案多行合并為一行
// if(!Strings.isNullOrEmpty(validKey))
//将BASE64編碼的私鑰字元串進行解碼
byte[] encodeByte = Base64.decodeBase64(validKey);
//==========
//pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[]
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(encodeByte);
RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.getPrivateKey());
byte[] pkcs1Bytes = pkcs1Key.getEncoded();//etc.
//==========
String type = "RSA PRIVATE KEY";
result = format2PemString(type, pkcs1Bytes);
return result;
}
//format PKCS#1 to PKCS#8
public static String formatPkcs1ToPkcs8(String rawKey) throws Exception {
String result = null;
//extract valid key content
String validKey = rawKey;//RsaPemUtil.extractFromPem(rawKey); // pem檔案多行合并為一行
// if(!Strings.isNullOrEmpty(validKey))
//将BASE64編碼的私鑰字元串進行解碼
byte[] encodeByte = Base64.decodeBase64(validKey);
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag); //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag
// ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte);
ASN1Object asn1Object = ASN1ObjectIdentifier.fromByteArray(encodeByte);
PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object);
byte[] pkcs8Bytes = privKeyInfo.getEncoded();
String type = "PRIVATE KEY";
// result = format2PemString(type, pkcs8Bytes); // 格式化為pem多行格式輸出
return Base64.encodeBase64String(pkcs8Bytes); // 直接一行字元串輸出
}
// Write to pem file
// 字元串換行顯示
private static String format2PemString(String type, byte[] privateKeyPKCS1) throws Exception {
PemObject pemObject = new PemObject(type, privateKeyPKCS1);
StringWriter stringWriter = new StringWriter();
PemWriter pemWriter = new PemWriter(stringWriter);
pemWriter.writeObject(pemObject);
pemWriter.close();
String pemString = stringWriter.toString();
return pemString;
}
//=== Testing ===
public static void main(String[] args) throws Exception {
String rawKey_pkcs1 = "";
String rawKey_pkcs8 = "";
rawKey_pkcs1 = "MIICXQIBAAKBgQDgDxka1U8SWI1vBY7pA1UiCVnrdtSgE+PpyTqe2YSEWCgkYQ2YsohZwsaUao7nya7QnBgRiPKEHgS/Eey+L9iwo32Sn5fUwb0nJ1+JeXRA6JsDEKpONJojIbF2nfgHLWsNn4bzn5Webc6WZLx0GyLTQuZGadFVuVq2dQqEsrq7HwIDAQABAoGAYtaGLo4WWXNywJzlE+kCbwdNAU/kL9FWYtT/5P7zNCZnXtTpWIi5GU+QpfvzmlAfq6qP+3w77wgG8/qGQsd8gGu3mydi0ImmD9sJdhhsJuWZhCMM+qmvSmvG/gvIr+bdEmPhpCQpa3BLveUkFDA/OnwfTVL6ruwZayMzuToB6WECQQD63Gx9DZVhYoSxR7qSmiGf/TjfOJusTcrmc27Z5X5MS36a3Ux9Z+c9EaYFldZ3cPzP521ugNVvZdovKqFKIcQ5AkEA5KYeKBVlkrLaamSEu5WAX3DqJ6iDRqEjzMoVad5B1I7kJHO+NijUxNHaWaSqLOHuk37X+EAjSTozzwOkKwbqFwJBAM1NhhAWBNHtcdEwddWzBJ/N+jRdPLIX/Fz7zZXQRruj8VpGkGn1lf6ZqfjaNuoLcyunKB0OnR6NCbIePl/QIKkCQGgEQjfN9BVWlBJOhCuqCWphvcQo3v+kktq5HCC7YYtHLfZ/SQrubEzVgtXBGUGtzpD+5VUkKGlJtwP4Dhkc3iUCQQCwiFKuQe/OdlkYk1L4mb0H0fzy+/6mYxyUqpTXUw/6BVDOyowvzieh9oh2ZhnQS7YPBWz5ZXzwUH4YVwGqxiwA";
rawKey_pkcs8 = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOAPGRrVTxJYjW8FjukDVSIJWet21KAT4+nJOp7ZhIRYKCRhDZiyiFnCxpRqjufJrtCcGBGI8oQeBL8R7L4v2LCjfZKfl9TBvScnX4l5dEDomwMQqk40miMhsXad+Actaw2fhvOflZ5tzpZkvHQbItNC5kZp0VW5WrZ1CoSyursfAgMBAAECgYBi1oYujhZZc3LAnOUT6QJvB00BT+Qv0VZi1P/k/vM0Jmde1OlYiLkZT5Cl+/OaUB+rqo/7fDvvCAbz+oZCx3yAa7ebJ2LQiaYP2wl2GGwm5ZmEIwz6qa9Ka8b+C8iv5t0SY+GkJClrcEu95SQUMD86fB9NUvqu7BlrIzO5OgHpYQJBAPrcbH0NlWFihLFHupKaIZ/9ON84m6xNyuZzbtnlfkxLfprdTH1n5z0RpgWV1ndw/M/nbW6A1W9l2i8qoUohxDkCQQDkph4oFWWSstpqZIS7lYBfcOonqINGoSPMyhVp3kHUjuQkc742KNTE0dpZpKos4e6Tftf4QCNJOjPPA6QrBuoXAkEAzU2GEBYE0e1x0TB11bMEn836NF08shf8XPvNldBGu6PxWkaQafWV/pmp+No26gtzK6coHQ6dHo0Jsh4+X9AgqQJAaARCN830FVaUEk6EK6oJamG9xCje/6SS2rkcILthi0ct9n9JCu5sTNWC1cEZQa3OkP7lVSQoaUm3A/gOGRzeJQJBALCIUq5B7852WRiTUviZvQfR/PL7/qZjHJSqlNdTD/oFUM7KjC/OJ6H2iHZmGdBLtg8FbPllfPBQfhhXAarGLAA=";
String formatKey1 = formatPkcs1ToPkcs8(rawKey_pkcs1);
String formatKey2 = formatPkcs8ToPkcs1(rawKey_pkcs8);
System.out.println(formatKey1);
System.out.println(formatKey2);
}
}
加解密方法
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* PKCS1 -> PKCS8 C# 生成密鑰對 JAVA進行對接
* RSA加解密工具類,實作公鑰加密私鑰解密和私鑰解密公鑰解密
*/
public class RSAPKCS1Utils {
private static final String src = "abcdefghijklmnopqrstuvwxyz";
public static void main(String[] args) throws Exception {
System.out.println("\n");
RSAKeyPair keyPair = generateKeyPair();
System.out.println("公鑰:" + keyPair.getPublicKey());
System.out.println("私鑰:" + keyPair.getPrivateKey());
System.out.println("\n");
// test1(keyPair, src);
System.out.println("\n");
// test2(keyPair, src);
System.out.println("\n");
String s = encryptByPrivateKeyPKCS1("MIIBOwIBAAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX6gUeMIlMHT2767JMpsTK\n" +
"aGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQJAPYFQlyu8405M656GxJuz\n" +
"1ii0rkjWCV6SjleJkmg2rJh+vvc/kE0NK84C9VyrUyj8D7DxcXx3GNJRVTdqS234\n" +
"AQIhAPjYLwMPTkf4W4k/KDJpKT+tFnhU1ZM76PxsyAFBFJ1/AiEA5POV+KJPYpOi\n" +
"SHcN/du3SaRMub8RBMR4Y3/lgANzmzECIF2Q28xouuRwy+pFJxYdWHcq2+IO8+dS\n" +
"hX40YNen4tp9AiEAmyixFCT7Y7Tln/J/GvFSD6g3DxJ7eB2l8Nh2MgEk0aECIQC2\n" +
"TRjpfptcbSIbpVHdr5C1kF29PMUdhgzh4TzApCWW0Q==", "20201202150544|2017648923|7842e11b");
System.out.println(s);
System.out.println(decryptByPublicKeyPKCS1("MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX\n" +
"6gUeMIlMHT2767JMpsTKaGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQ==", s));
}
/**
* 公鑰加密私鑰解密
*/
private static void test1(RSAKeyPair keyPair, String source) throws Exception {
System.out.println("***************** 公鑰加密私鑰解密開始 *****************");
String text1 = encryptByPublicKey(keyPair.getPublicKey(), source);
System.out.println("===================== 分隔 =======================");
String user = "lrZL1Xnf8Tib3WBIRfKqG5gco4HsD7QqllZzvoOcbnRoaBhIC0h/+q9cA+/8pqJHgZZarH+1ia+WipeF6iAnkw==";
String userPrivateKey = "MIIBOwIBAAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX6gUeMIlMHT2767JMpsTK\n" +
"aGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQJAPYFQlyu8405M656GxJuz\n" +
"1ii0rkjWCV6SjleJkmg2rJh+vvc/kE0NK84C9VyrUyj8D7DxcXx3GNJRVTdqS234\n" +
"AQIhAPjYLwMPTkf4W4k/KDJpKT+tFnhU1ZM76PxsyAFBFJ1/AiEA5POV+KJPYpOi\n" +
"SHcN/du3SaRMub8RBMR4Y3/lgANzmzECIF2Q28xouuRwy+pFJxYdWHcq2+IO8+dS\n" +
"hX40YNen4tp9AiEAmyixFCT7Y7Tln/J/GvFSD6g3DxJ7eB2l8Nh2MgEk0aECIQC2\n" +
"TRjpfptcbSIbpVHdr5C1kF29PMUdhgzh4TzApCWW0Q==";
String userPublicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX\n" +
"6gUeMIlMHT2767JMpsTKaGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQ==";
// String text2 = decryptByPrivateKey(keyPair.getPrivateKey(), text1);
String text2 = decryptByPrivateKey(userPublicKey, user);
System.out.println("加密前:" + user);
System.out.println("加密後:" + user);
System.out.println("解密後:" + text2);
if (source.equals(text2)) {
System.out.println("解密字元串和原始字元串一緻,解密成功");
} else {
System.out.println("解密字元串和原始字元串不一緻,解密失敗");
}
System.out.println("***************** 公鑰加密私鑰解密結束 *****************");
}
/**
* 私鑰加密公鑰解密
*
* @throws Exception
*/
private static void test2(RSAKeyPair keyPair, String source) throws Exception {
String user = "lrZL1Xnf8Tib3WBIRfKqG5gco4HsD7QqllZzvoOcbnRoaBhIC0h/+q9cA+/8pqJHgZZarH+1ia+WipeF6iAnkw==";
String userPrivateKey = "MIIBOwIBAAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX6gUeMIlMHT2767JMpsTK\n" +
"aGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQJAPYFQlyu8405M656GxJuz\n" +
"1ii0rkjWCV6SjleJkmg2rJh+vvc/kE0NK84C9VyrUyj8D7DxcXx3GNJRVTdqS234\n" +
"AQIhAPjYLwMPTkf4W4k/KDJpKT+tFnhU1ZM76PxsyAFBFJ1/AiEA5POV+KJPYpOi\n" +
"SHcN/du3SaRMub8RBMR4Y3/lgANzmzECIF2Q28xouuRwy+pFJxYdWHcq2+IO8+dS\n" +
"hX40YNen4tp9AiEAmyixFCT7Y7Tln/J/GvFSD6g3DxJ7eB2l8Nh2MgEk0aECIQC2\n" +
"TRjpfptcbSIbpVHdr5C1kF29PMUdhgzh4TzApCWW0Q==";
String userPublicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN6NUNrcGYqPm4EQ/q/6dzTerulZnagX\n" +
"6gUeMIlMHT2767JMpsTKaGkYtp8jp3Jk0nyKG/MUZaUmRHDfQC1bCk8CAwEAAQ==";
System.out.println("***************** 私鑰加密公鑰解密開始 *****************");
String text1 = encryptByPrivateKey(keyPair.getPrivateKey(), source);
String text2 = decryptByPublicKey(keyPair.getPublicKey(), text1);
System.out.println("加密前:" + source);
System.out.println("加密後:" + text1);
System.out.println("解密後:" + text2);
if (source.equals(text2)) {
System.out.println("解密字元串和原始字元串一緻,解密成功");
} else {
System.out.println("解密字元串和原始字元串不一緻,解密失敗");
}
System.out.println("***************** 私鑰加密公鑰解密結束 *****************");
}
/**
* 公鑰解密
*
* @param publicKeyText
* @param text
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 公鑰解密PKCS1 - 轉PKCS8(C# -> JAVA)
*
* @param publicKeyText
* @param text
* @return
* @throws Exception
*/
public static String decryptByPublicKeyPKCS1(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 私鑰加密PKCS8
*
* @param privateKeyText
* @param text
* @return
* @throws Exception
*/
public static String encryptByPrivateKey(String privateKeyText, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 私鑰加密PKCS1 - 轉PKCS1(C# -> JAVA)
*
* @param privateKeyText
* @param text
* @return
* @throws Exception
*/
public static String encryptByPrivateKeyPKCS1(String privateKeyText, String text) throws Exception {
String pkcs8 = RsaPkcsTransformer.formatPkcs1ToPkcs8(privateKeyText);
// 生成PrivateKey(前提對PKCS1變換為PKCS8)
byte[] keyByte = cn.hutool.core.codec.Base64.decode(pkcs8);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec encodeRule = new PKCS8EncodedKeySpec(keyByte);
PrivateKey privatekey = keyfactory.generatePrivate(encodeRule);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, privatekey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 私鑰解密
*
* @param privateKeyText
* @param text
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String privateKeyText, String text) throws Exception {
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(Base64.decodeBase64(text));
return new String(result);
}
/**
* 公鑰加密
*
* @param publicKeyText
* @param text
* @return
*/
public static String encryptByPublicKey(String publicKeyText, String text) throws Exception {
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyText));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(text.getBytes());
return Base64.encodeBase64String(result);
}
/**
* 建構RSA密鑰對
*
* @return
* @throws NoSuchAlgorithmException
*/
public static RSAKeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
RSAKeyPair rsaKeyPair = new RSAKeyPair(publicKeyString, privateKeyString);
return rsaKeyPair;
}
/**
* RSA密鑰對對象
*/
public static class RSAKeyPair {
private String publicKey;
private String privateKey;
public RSAKeyPair(String publicKey, String privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public String getPrivateKey() {
return privateKey;
}
}
}