RSA Encryption and Decryption
RSA asymmetric encryption involves many tasks, which can be decomposed into the following sub-tasks:
- Signing, encapsulated in
com.ajaxjs.util.cryptography.rsa.DoSignature - Signature verification, encapsulated in
com.ajaxjs.util.cryptography.rsa.DoVerify - Key management, encapsulated in
com.ajaxjs.util.cryptography.rsa.KeyMgr - RSA encryption and decryption itself
Each will be introduced separately below.
Signing
Input parameters include algorithm, input data, and private key. Execute sign() to return the signature. The involved types are as follows:
- Input data, can be
byte[]or string - Private key, can be a PrivateKey object or string. If it's a string, it will be restored to a PrivateKey object through
KeyMgr.restoreKey - The returned signature data is
byte[], andsignToString()can be called to return a base64-encoded string
// Generate public and private keys
KeyMgr keyMgr = new KeyMgr(Constant.RSA, 2048);
keyMgr.generateKeyPair();
String privateKey = keyMgr.getPrivateKeyStr();
byte[] helloWorlds = new DoSignature(Constant.SHA256_RSA).setStrData("hello world").setPrivateKeyStr(privateKey).sign();
String result = new DoSignature(Constant.SHA256_RSA).setStrData("hello world").setPrivateKeyStr(privateKey).signToString();
assertEquals(new Base64Utils(helloWorlds).encodeAsString(), result);
The private key is generated by KeyMgr. RSA key sizes are restricted to 2048, 3072, or 4096 bits; 2048 bits is the minimum accepted size.
Signature Verification
Input parameters include algorithm, input data, signature data, and public key. Execute verify() to verify the signature. The involved types are as follows:
- Input data, can be
byte[]or string - Signature data, can be
byte[]or Base64 string - Public key, can be a PublicKey object or string. If it's a string, it will be restored to a PublicKey object through
KeyMgr - Whether the returned signature is valid, is
boolean
// Generate public and private keys
KeyMgr keyMgr = new KeyMgr(Constant.RSA, 2048);
keyMgr.generateKeyPair();
String publicKey = keyMgr.getPublicKeyStr(), privateKey = keyMgr.getPrivateKeyStr();
String result = new DoSignature(Constant.SHA256_RSA).setStrData("hello world").setPrivateKeyStr(privateKey).signToString();
boolean verified = new DoVerify(Constant.SHA256_RSA).setStrData("hello world").setPublicKeyStr(publicKey).setSignatureBase64(result).verify();
assertTrue(verified);
The key pair can be generated through KeyMgr. Signing and verification validate their required input, signature, and key state before invoking JCA.
RSA Encryption and Decryption
Nothing more to say, directly show the API examples.
// Generate public and private keys
KeyMgr keyMgr = new KeyMgr(Constant.RSA, 2048);
keyMgr.generateKeyPair();
String publicKey = keyMgr.getPublicKeyStr(), privateKey = keyMgr.getPrivateKeyStr();
// System.out.println("Public Key Encryption--------Private Key Decryption");
String word = "你好,世界!";
byte[] encWord = KeyMgr.publicKeyEncrypt(word.getBytes(), publicKey);
String decWord = new String(KeyMgr.privateKeyDecrypt(encWord, privateKey));
String eBody = new Base64Utils(encWord).encodeAsString();
String decWord2 = new String(KeyMgr.privateKeyDecrypt(new Base64Utils(eBody).decode(), privateKey));
System.out.println("Before Encryption: " + word + "\n\rCiphertext: " + eBody + "\nAfter Decryption: " + decWord2);
assertEquals(word, decWord);
// System.out.println("Private Key Encryption--------Public Key Decryption");
String english = "Hello, World!";
byte[] encEnglish = KeyMgr.privateKeyEncrypt(english.getBytes(), privateKey);
String decEnglish = new String(KeyMgr.publicKeyDecrypt(encEnglish, publicKey));
// System.out.println("Before Encryption: " + english + "\n\r" + "After Decryption: " + decEnglish);
assertEquals(english, decEnglish);
// System.out.println("Private Key Signing——Public Key Signature Verification");
// Generate signature
String sign = new DoSignature(Constant.SHA256_RSA).setPrivateKeyStr(privateKey).setData(encEnglish).signToString();
// System.out.println("Signature:\r" + sign);
// Verify signature
assertTrue(new DoVerify(Constant.SHA256_RSA).setPublicKeyStr(publicKey).setData(encEnglish).setSignatureBase64(sign).verify());
Key Management
Some utility methods for keys are in KeyMgr, including both public and private keys. Generally, open-source projects like to encapsulate KeyPair as a Map, but the author thinks using KeyPair itself is sufficient. If not fully satisfied, certain methods can be added, such as getPublicKeyBytes(), getPublicKeyStr(), getPublicToPem(), which are clearer compared to using Map.
Additionally, the keys themselves can also be encrypted and decrypted for higher security.
Never write private-key material to logs or exception messages. Invalid-private-key errors intentionally contain only a sanitized description.