RSA Encryption and Signature
1. RSA Encryption
OAEP (Optimal Asymmetric Encryption Padding):
The default RSA encryption padding scheme, known for its high security.
Enhances security using randomness and hash functions.
Default configuration:
Hash function:
SHA-256
(specified byOAEPWithSHA-256AndMGF1Padding
).Mask Generation Function (MGF):
MGF1
.MGF hash function: Same as the main hash function (e.g.,
SHA-256
).Label: Defaults to empty.
Code Example:
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
2. RSA Signature
PSS (Probabilistic Signature Scheme):
The default RSA signature padding scheme, known for its high security.
Uses random salt, ensuring different signatures for the same data.
Default configuration:
Hash function:
SHA-256
(specified bySHA256withRSA/PSS
).Mask Generation Function (MGF):
MGF1
.MGF hash function: Same as the main hash function (e.g.,
SHA-256
).Salt length: Defaults to the output length of the hash function (e.g., 32 bytes for
SHA-256
).
Code Example:
Signature signature = Signature.getInstance("SHA256withRSA/PSS"); signature.initSign(privateKey); signature.update(data); byte[] signatureBytes = signature.sign();
3. PKCS#1 and PKCS#8
PKCS#1:
Specifically for RSA keys.
Private key format:
-----BEGIN RSA PRIVATE KEY-----
.Public key format:
-----BEGIN RSA PUBLIC KEY-----
.
PKCS#8:
A generic key format supporting multiple algorithms (e.g., RSA, ECDSA).
Private key format:
-----BEGIN PRIVATE KEY-----
.Public key format:
-----BEGIN PUBLIC KEY-----
.
Default Key Generation:
- Java and Android generate PKCS#8 private keys and X.509 public keys by default.
Cross-Format Signature Verification:
- Signatures created with PKCS#8 private keys can be verified using PKCS#1 public keys without conversion.
4. MGF1 (Mask Generation Function 1)
Purpose:
- Generates variable-length masks for use in OAEP and PSS.
Default Configuration:
Used by default in OAEP and PSS.
The MGF hash function matches the main hash function (e.g.,
SHA-256
).
5. Code Example: Cross-Format Signature Verification
1. Generate a PKCS#8 Key Pair
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate(); // PKCS#8 private key
PublicKey publicKey = keyPair.getPublic(); // X.509 public key
2. Sign Data with PKCS#8 Private Key (PSS Padding)
Signature signature = Signature.getInstance("SHA256withRSA/PSS");
signature.initSign(privateKey);
signature.update(data);
byte[] signatureBytes = signature.sign();
3. Convert X.509 Public Key to PKCS#1 Format
// Assume you have converted the X.509 public key to PKCS#1 format
String pkcs1PublicKeyPEM = "-----BEGIN RSA PUBLIC KEY-----\n" +
"MIIBCgKCAQEA...\n" +
"-----END RSA PUBLIC KEY-----";
// Parse the PKCS#1 public key
byte[] pkcs1PublicKeyBytes = Base64.getDecoder().decode(pkcs1PublicKeyPEM
.replace("-----BEGIN RSA PUBLIC KEY-----", "")
.replace("-----END RSA PUBLIC KEY-----", "")
.replaceAll("\\s", ""));
// Use BouncyCastle to parse the PKCS#1 public key
RSAPublicKey pkcs1PublicKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
.generatePublic(new X509EncodedKeySpec(pkcs1PublicKeyBytes));
4. Verify Signature with PKCS#1 Public Key
signature.initVerify(pkcs1PublicKey); // Use PKCS#1 public key
signature.update(data);
boolean isValid = signature.verify(signatureBytes);
System.out.println("Signature is valid: " + isValid);
6. Summary
OAEP is the recommended padding scheme for RSA encryption, using
MGF1
by default.PSS is the recommended padding scheme for RSA signatures, using
MGF1
by default.PKCS#8 is the default key format, while PKCS#1 is an older format. They can be converted between each other.
Signatures created with PKCS#8 private keys can be verified using PKCS#1 public keys without conversion.