RSA Generate Key
- Generate Key pair
- Public Key(Shorter) and Private Key(Longer)
- KeyFactory : RSA
/**
* 密钥对生成 generateKey
*
* @return java.lang.String[]
* @author Created by ivan
* @since 2023/6/13 14:46
*/
public static String[] generateKey() {
String[] keyP = new String[2];
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance(RSA_KEY_FACTORY);
kpg.initialize(RSA_KEY_SIZE);
KeyPair keyPair = kpg.generateKeyPair();
keyP[0] = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
keyP[1] = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
log.error("RsaHelper generateKey Failed", e);
keyP[0] = RSA_PUBLIC_KEY;
keyP[1] = RSA_PRIVATE_KEY;
}
return keyP;
}
RSA Sign
- Generate signurate for input data
- Sign with Private Key
- Verify Sign with Public Key
- Sign Algorithm : SHA256withRSA
/**
* 计算签名 generateSign
*
* @param data data
* @param key private key
* @return java.lang.String
* @author Created by ivan
* @since 2023/6/13 14:46
*/
public static String generateSign(String data, String key) {
String result = "";
try {
Signature signature = Signature.getInstance(RSA_SIGN_ALGORITHM);
PrivateKey priKey =
KeyFactory.getInstance(RSA_KEY_FACTORY)
.generatePrivate(
new PKCS8EncodedKeySpec(
Base64.getDecoder().decode(key.getBytes(StandardCharsets.UTF_8))));
signature.initSign(priKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
byte[] signed = signature.sign();
result = new String(Base64.getEncoder().encode(signed), StandardCharsets.UTF_8);
} catch (Exception e) {
log.error("RsaHelper,generateSign, error", e);
}
return result;
}
/**
* 校验签名 verifySign
*
* @param data data
* @param sign sign
* @param key pubkey
* @return boolean
* @author Created by ivan
* @since 2023/6/13 15:56
*/
public static boolean verifySign(String data, String sign, String key) {
boolean result = false;
try {
Signature signature = Signature.getInstance(RSA_SIGN_ALGORITHM);
PublicKey pubKey =
KeyFactory.getInstance(RSA_KEY_FACTORY)
.generatePublic(
new X509EncodedKeySpec(
Base64.getDecoder().decode(key.getBytes(StandardCharsets.UTF_8))));
signature.initVerify(pubKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
result = signature.verify(Base64.getDecoder().decode(sign.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
log.error("RsaHelper,verifySign, error", e);
}
return result;
}
RSA Encrypt/Decrypt
- Encrypt with Public Key
- Decrypt with Private Key
- Do part cipher for long data : 256 bytes
- Key size : 2048
- Cipher Algorithm: RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING
- Notice: PriKey Encrypt/PubKey Decrypt is not secure and not allowed with the given cipher
/**
* RSA ENCODER CIPHER rsaEncCipher
*
* @param source source
* @param rsaKey rsaKey
* @param cipher cipher
* @return java.lang.String
* @author Created by ivan
* @since 2023/2/2 15:48
*/
private static String rsaEncCipher(String source, Key rsaKey, Cipher cipher)
throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
cipher.init(Cipher.ENCRYPT_MODE, rsaKey);
byte[] datas = source.getBytes(StandardCharsets.UTF_8);
int inputLen = datas.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
while (inputLen - offset > 0) {
if (inputLen - offset > 245) {
cache = cipher.doFinal(datas, offset, 245);
} else {
cache = cipher.doFinal(datas, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * 245;
}
String encryptData = Base64.getEncoder().encodeToString(out.toByteArray());
out.close();
return encryptData;
}
/**
* RSA DECODER CIPHER rsaDecCipher
*
* @param cipherText cipherText
* @param rsaKey rsaKey
* @param cipher cipher
* @return java.lang.String
* @author Created by ivan
* @since 2023/2/2 15:48
*/
private static String rsaDecCipher(String cipherText, Key rsaKey, Cipher cipher)
throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
cipher.init(Cipher.DECRYPT_MODE, rsaKey);
byte[] inputByte = Base64.getDecoder().decode(cipherText.getBytes(StandardCharsets.UTF_8));
int inputLen = inputByte.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offset = 0;
byte[] cache;
int i = 0;
while (inputLen - offset > 0) {
if (inputLen - offset > 256) {
cache = cipher.doFinal(inputByte, offset, 256);
} else {
cache = cipher.doFinal(inputByte, offset, inputLen - offset);
}
out.write(cache, 0, cache.length);
i++;
offset = i * 256;
}
String data = out.toString();
out.close();
return data;
}
/**
* RSA_2048公钥加密 encryptByRSA2048PubKey
*
* @param data 原文
* @param decoded decoded
* @return java.lang.String
* @author Created by ivan
* @since 2023/2/2 14:40
*/
private static String encryptByRSA2048PubKey(String data, byte[] decoded) {
try {
RSAPublicKey rsaPublicKey =
(RSAPublicKey)
KeyFactory.getInstance(RSA_KEY_FACTORY)
.generatePublic(new X509EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance(RSA_CIPHER_ALGORITHM_PUB2PRI);
return rsaEncCipher(data, rsaPublicKey, cipher);
} catch (Exception e) {
log.error("encryptByRSA2048PubKey error.", e);
return null;
}
}
/**
* RSA_2048私钥解密 decryptByRSA2048PriKey
*
* @param cipherText cipherText
* @param decoded decoded
* @return java.lang.String
* @author Created by ivan
* @since 2023/2/2 14:40
*/
private static String decryptByRSA2048PriKey(String cipherText, byte[] decoded) {
try {
RSAPrivateKey rsaPrivateKey =
(RSAPrivateKey)
KeyFactory.getInstance(RSA_KEY_FACTORY)
.generatePrivate(new PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance(RSA_CIPHER_ALGORITHM_PUB2PRI);
return rsaDecCipher(cipherText, rsaPrivateKey, cipher);
} catch (Exception e) {
log.error("decryptByRSA2048PriKey error.", e);
return null;
}
}
Unit Test
public static final String data = "test message";
@Test
void sign() {
String[] keys = RsaHelper.generateKey();
Assertions.assertEquals(2, keys.length);
log.info(
"Pub key:{}\n{},\n Pri Key:{}\n{}", keys[0].length(), keys[0], keys[1].length(), keys[1]);
String sign = RsaHelper.generateSign(data, keys[1]);
log.info("sign:{}\n{}", sign.length(), sign);
Assertions.assertTrue(RsaHelper.verifySign(data, sign, keys[0]));
}
@Test
void encrypt() {
String[] keys = RsaHelper.generateKey();
Assertions.assertEquals(2, keys.length);
log.info(
"Pub key:{}\n{},\n Pri Key:{}\n{}", keys[0].length(), keys[0], keys[1].length(), keys[1]);
String encodePub = RsaHelper.encryptByPubKey(data, keys[0]);
String decodePri = RsaHelper.decryptByPriKey(encodePub, keys[1]);
Assertions.assertEquals(data, decodePri);
}
@Test
void generateKey() {
String[] keys = RsaHelper.generateKey();
log.info("Pub key:{},\n Pri Key:{}", keys[0], keys[1]);
}
本文由 Ivan Dong 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jun 13, 2023 at 10:17 am