public class RSA {
static final String KEY_ALGORITHM = "RSA";
static final String CIPHER_ECB_PKCS1 = "RSA/ECB/PKCS1Padding";
public static void main(String[] args) throws Exception {
String data = "斯柯達U*(Sfsad7f()*^%%$";
// 1. 公鑰加密,私鑰解密
encryptDecryptByPublicKey(data);
// 2. 私鑰加密,公鑰解密(簽名場景)
encryptDecryptByPrivateKey(data);
// 3. 指定 Padding 模式
encryptDecryptWithExplicitPadding(data);
}
static void encryptDecryptByPublicKey(String str) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
KeyPair kp = kpg.generateKeyPair();
PublicKey pub = kp.getPublic();
PrivateKey pri = kp.getPrivate();
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); // 默認 ECB/PKCS1Padding
cipher.init(Cipher.ENCRYPT_MODE, pub);
byte[] enc = cipher.doFinal(str.getBytes());
System.out.println("公鑰加密: " + Arrays.toString(enc));
cipher.init(Cipher.DECRYPT_MODE, pri);
byte[] dec = cipher.doFinal(enc);
System.out.println("私鑰解密: " + new String(dec));
}
// 其他方法類似...
}
注意:RSA 直接加密數據長度受限於密鑰長度(1024bit 密鑰最多加密 117 字節)。實際項目中採用混合加密:AES 加密數據,RSA 加密 AES 密鑰。
public class DSA {
static final String KEY_ALGORITHM = "DSA";
static final String SIGNATURE_ALGORITHM = "DSA"; // 或 "SHA1withDSA"
static final String DEFAULT_SEED = "$%^*%^()(HJG8awfjas7";
public static void main(String[] args) throws Exception {
String str = "!@#$!#^$#&ZXVDF呆兵工路愛著你*()_+";
byte[] data = str.getBytes();
Map<String, Object> keyMap = initKey(); // 生成密鑰對
PublicKey pub = (PublicKey) keyMap.get("DSAPublicKey");
PrivateKey pri = (PrivateKey) keyMap.get("DSAPrivateKey");
String sign = sign(data, getPrivateKey(keyMap)); // 私鑰簽名
System.out.println("簽名: " + sign);
boolean v1 = verify("aaa".getBytes(), getPublicKey(keyMap), sign); // 錯誤數據
System.out.println("錯誤數據驗證: " + v1); // false
boolean v2 = verify(data, getPublicKey(keyMap), sign); // 正確數據
System.out.println("正確數據驗證: " + v2); // true
}
static Map<String, Object> initKey(String seed) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
SecureRandom sr = new SecureRandom(seed.getBytes());
kpg.initialize(640, sr); // 512-1024 位,64 的倍數
KeyPair kp = kpg.genKeyPair();
Map<String, Object> map = new HashMap<>();
map.put("DSAPublicKey", kp.getPublic());
map.put("DSAPrivateKey", kp.getPrivate());
return map;
}
static String sign(byte[] data, String privateKeyBase64) throws Exception {
byte[] keyBytes = decryptBASE64(privateKeyBase64);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey pri = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(spec);
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initSign(pri);
sig.update(data);
return encryptBASE64(sig.sign());
}
static boolean verify(byte[] data, String publicKeyBase64, String signBase64) throws Exception {
byte[] keyBytes = decryptBASE64(publicKeyBase64);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
PublicKey pub = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(spec);
Signature sig = Signature.getInstance(SIGNATURE_ALGORITHM);
sig.initVerify(pub);
sig.update(data);
return sig.verify(decryptBASE64(signBase64));
}
// BASE64 編解碼輔助方法...
}
將 KEY_ALGORITHM="RSA"、SIGNATURE_ALGORITHM="MD5withRSA" 或 SHA256withRSA,流程與 DSA 完全一致。RSA 簽名較慢,但兼容性更廣。
OAEPWithSHA-256AndMGF1Padding,避免 PKCS#1 v1.5 填充被選擇密文攻擊。RSA-PSS (SHA256withRSAandMGF1) 或 ECDSA,DSA 漸被淘汰(密鑰長度限制)。