Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
magicianlib committed Dec 10, 2024
1 parent 21d3433 commit f971456
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.concurrent.Callable;
import java.util.function.Function;

/**
* <p>该类提供常见的 HashWithRSA 组合算法,用于提供数据签名和验签。</p>
Expand All @@ -19,21 +18,24 @@
* 加密和签名都是为了安全性考虑,但有所不同。加密是为了防止信息被泄露,签名是为了防止信息被篡改。</p>
*
* <h3>加密过程:</h3>
*
* <ul>
* <li>A生成一对密钥(公钥和私钥)。私钥不公开,A自己保留。公钥为公开的,任何人可以获取。</li>
* <li>A传递自己的公钥给B,B使用A的<em>公钥对消息进行加密</em>。</li>
* <li>A接收到B加密的消息,利用A自己的<em>私钥对消息进行解密</em></li>
* </ul>
* <p>整个过程中,只用A的私钥才能对消息进行解密,防止消息被泄露。</p><br>
*
* <p>整个过程中,只用A的私钥才能对消息进行解密,防止消息被泄露。</p>
*
* <h3>签名过程:</h3>
*
* <ul>
* <li>A生成一对密钥(公钥和私钥)。私钥不公开,A自己保留。公钥为公开的,任何人可以获取。</li>
* <li>A用自己的私钥对消息进行加签,形成签名,并将签名和消息本身一起传递给B。</li>
* <li>B收到消息后,通过A的公钥进行验签。如果验签成功,则证明消息是A发送的。</li>
* </ul>
* <p>
* 整个过程,只有使用A私钥签名的消息才能被验签成功。即使知道了消息内容,也无法伪造签名,防止消息被篡改。
*
* <p>整个过程,只有使用A私钥签名的消息才能被验签成功。即使知道了消息内容,也无法伪造签名,防止消息被篡改。
*/
public enum HashWithRSA {

Expand Down Expand Up @@ -70,23 +72,23 @@ public byte[] signature(byte[] priKey, byte[] plaintext) throws NoSuchAlgorithmE
return spi.sign();
}

public <R> R signature(byte[] priKey, byte[] plaintext, Function<byte[], R> production) throws Exception {
public <R> R signature(byte[] priKey, byte[] plaintext, Production<R> production) throws Exception {
return production.apply(signature(priKey, plaintext));
}

public byte[] signature(Callable<byte[]> priKey, Callable<byte[]> plaintext) throws Exception {
return signature(priKey.call(), plaintext.call());
}

public <R> R signature(Callable<byte[]> priKey, Callable<byte[]> plaintext, Function<byte[], R> production) throws Exception {
public <R> R signature(Callable<byte[]> priKey, Callable<byte[]> plaintext, Production<R> production) throws Exception {
return production.apply(signature(priKey, plaintext));
}

public byte[] signature(String priKeyBase64, String plaintext) throws Exception {
return signature(decodeBase64ToByte(priKeyBase64), plaintext.getBytes(StandardCharsets.UTF_8));
}

public <R> R signature(String priKeyBase64, String plaintext, Function<byte[], R> production) throws Exception {
public <R> R signature(String priKeyBase64, String plaintext, Production<R> production) throws Exception {
return production.apply(signature(priKeyBase64, plaintext));
}

Expand Down Expand Up @@ -130,4 +132,12 @@ public static String toBase64String(byte[] encoded) {
public static byte[] decodeBase64ToByte(String decoded) {
return java.util.Base64.getDecoder().decode(decoded);
}

@FunctionalInterface
public interface Production<R> {
/**
* @return the function result
*/
R apply(byte[] data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.function.Function;

/**
* <p>HMAC(Hash-based Message Authentication Code)是一种使用哈希函数
Expand Down Expand Up @@ -40,7 +39,7 @@ public byte[] hmac(byte[] secret, byte[] plaintext) throws NoSuchAlgorithmExcept
return mac.doFinal(plaintext);
}

public <R> R hmac(byte[] secret, byte[] plaintext, Function<byte[], R> production) throws NoSuchAlgorithmException, InvalidKeyException {
public <R> R hmac(byte[] secret, byte[] plaintext, Production<R> production) throws NoSuchAlgorithmException, InvalidKeyException {
Mac mac = Mac.getInstance(this.name());
SecretKeySpec keySpec = new SecretKeySpec(secret, algorithm);
mac.init(keySpec);
Expand All @@ -55,6 +54,14 @@ public String hmacBase64(String secret, String plaintext) throws NoSuchAlgorithm
return hmac(secret.getBytes(StandardCharsets.UTF_8), plaintext.getBytes(StandardCharsets.UTF_8), Base64::encodeBase64String);
}

@FunctionalInterface
public interface Production<R> {
/**
* @return the function result
*/
R apply(byte[] data);
}

public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {

String secret = "f$s1f@9.";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.online4edu.dependencies.utils.math;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
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 java.util.function.Function;

/**
* Rsa 非对称加密解密工具类
Expand All @@ -18,52 +18,67 @@ public class RsaUtil {
/**
* 公钥加密
*
* @param plainText 带加密文本
* @param publicKey 公钥
* @param plaintext 明文
* @param pubKey 公钥
*/
public static <R> R encrypt(String plainText, PublicKey publicKey, Function<byte[], R> production) throws Exception {
public static <R> R encrypt(String plaintext, PublicKey pubKey, Production<R> production) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(plainText.getBytes()); // 密文
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); // 密文
return production.apply(encrypted);
}

public static <R> R encrypt(String plainText, String publicKeyBase64, Function<byte[], R> production) throws Exception {
/**
* 公钥加密
*
* @param pubKeyBase64 base64格式公钥
*/
public static <R> R encrypt(String plaintext, String pubKeyBase64, Production<R> production) throws Exception {
// 公钥证书
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeBase64ToByte(publicKeyBase64));
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeBase64ToByte(pubKeyBase64));
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);

return encrypt(plainText, publicKey, production); // 加密
return encrypt(plaintext, publicKey, production); // 加密
}

public static String encryptToBase64String(String plainText, String publicKeyBase64) throws Exception {
/**
* 公钥加密
*
* @param pubKeyBase64 base64格式公钥
*/
public static String encryptToBase64String(String plaintext, String pubKeyBase64) throws Exception {
// 公钥证书
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeBase64ToByte(publicKeyBase64));
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeBase64ToByte(pubKeyBase64));
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);

return encrypt(plainText, publicKey, RsaUtil::toBase64String); // 加密
return encrypt(plaintext, publicKey, RsaUtil::toBase64String); // 加密
}

/**
* 私钥解密
*
* @param encryptedText 密文
* @param privateKey 撕咬
* @param encrypted 密文
* @param priKey 私钥
*/
public static <R> R decrypt(String encryptedText, PrivateKey privateKey, Function<byte[], R> production) throws Exception {
public static <R> R decrypt(String encrypted, PrivateKey priKey, Production<R> production) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decrypted = cipher.doFinal(decodeBase64ToByte(encryptedText));
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] decrypted = cipher.doFinal(decodeBase64ToByte(encrypted));
return production.apply(decrypted);
}

public static String decryptToString(String encryptedText, PrivateKey privateKey) throws Exception {
return decrypt(encryptedText, privateKey, String::new);
public static String decryptToString(String encrypted, PrivateKey priKey) throws Exception {
return decrypt(encrypted, priKey, String::new);
}

public static <R> R decrypt(String encryptedText, String privateKeyBase64, Function<byte[], R> production) throws Exception {
/**
* 私钥解密
*
* @param priKeyBase64 base64格式私钥
*/
public static <R> R decrypt(String encryptedText, String priKeyBase64, Production<R> production) throws Exception {
// 私钥证书
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodeBase64ToByte(privateKeyBase64));
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodeBase64ToByte(priKeyBase64));
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);

return decrypt(encryptedText, privateKey, production);
Expand All @@ -81,6 +96,14 @@ public static byte[] decodeBase64ToByte(String decoded) {
return java.util.Base64.getDecoder().decode(decoded);
}

@FunctionalInterface
public interface Production<R> {
/**
* @return the function result
*/
R apply(byte[] data);
}

/**
* 生成密匙对
*
Expand Down

0 comments on commit f971456

Please sign in to comment.