YOUSEFUL / DELPHI / COMPONENTS
TAtlasRsa
RSA with OAEP (SHA-256) encryption of short secrets and PSS (SHA-256, 32-byte salt) signatures, for keys of 2048 to 8192 bits.
Description
RSA encryption only takes short messages: at most the modulus size minus 66 bytes (190 bytes for 2048 bits, 318 for 3072). Use it to wrap a random content key, and seal the data itself with TAtlasSecretBox. OAEP and PSS are both randomised, so the same input gives different ciphertexts and signatures. Ciphertexts and signatures are as long as the modulus.
PKCS#1 v1.5 encryption, raw RSA, SHA-1 and keys below 2048 bits are not offered. Generating an RSA key pair is much slower than an elliptic-curve pair, and the time varies because it searches for random primes (one 3072-bit pair took about half a second on the machine used to write this page), so generate once and store it. Decrypt fails with one message whatever went wrong inside. Verify returns False for any mismatch and raises only when the public key cannot be imported. RSA is covered by round-trip tests only; there is no interoperability test against another library.
Members
| Member | Kind | What it does |
|---|---|---|
GenerateKeyPair | method | Returns a new key pair of Bits bits: 2048 to 8192, in steps of 64; anything else raises EAtlasCryptoError. |
Encrypt | method | Encrypts Plain with RSA-OAEP (SHA-256, no label) and returns a ciphertext as long as the modulus. |
Decrypt | method | Returns the plaintext, or raises EAtlasCryptoError (Decryption failed: wrong key, or the data was altered) for an altered ciphertext or the wrong key, without revealing which check failed. |
Sign | method | Returns an RSA-PSS signature (SHA-256 digest of Data, 32-byte salt), as long as the modulus. |
Verify | method | True when Signature is a valid PSS signature of Data for PublicKey. |
KeyBits | method | Returns the modulus size in bits read from the header of an RSA public or private blob. |
Methods
GenerateKeyPair method
class function GenerateKeyPair(Bits: Integer = 3072): TAtlasKeyPair; static;Returns a new key pair of Bits bits: 2048 to 8192, in steps of 64; anything else raises EAtlasCryptoError. The default 3072 bits matches the strength of P-256.
Pair := TAtlasRsa.GenerateKeyPair(2048);Encrypt method
class function Encrypt(const PublicKey, Plain: TBytes): TBytes; static;Encrypts Plain with RSA-OAEP (SHA-256, no label) and returns a ciphertext as long as the modulus. A message longer than the limit raises EAtlasCryptoError (Encrypting with RSA (is the message longer than the key allows?) failed ...).
Wrapped := TAtlasRsa.Encrypt(Pair.PublicKey, Key);Decrypt method
class function Decrypt(const PrivateKey, Cipher: TBytes): TBytes; static;Returns the plaintext, or raises EAtlasCryptoError (Decryption failed: wrong key, or the data was altered) for an altered ciphertext or the wrong key, without revealing which check failed. A public key blob in place of the private key raises a key import error.
Key := TAtlasRsa.Decrypt(Pair.PrivateKey, Wrapped);Sign method
class function Sign(const PrivateKey, Data: TBytes): TBytes; static;Returns an RSA-PSS signature (SHA-256 digest of Data, 32-byte salt), as long as the modulus.
Signature := TAtlasRsa.Sign(Pair.PrivateKey, Data);Verify method
class function Verify(const PublicKey, Data, Signature: TBytes): Boolean; static;True when Signature is a valid PSS signature of Data for PublicKey. False for any mismatch, including an empty or wrong-length signature. Raises EAtlasCryptoError when PublicKey cannot be imported as an RSA public key.
Valid := TAtlasRsa.Verify(Pair.PublicKey, Data, Signature);KeyBits method
class function KeyBits(const Key: TBytes): Integer; static;Returns the modulus size in bits read from the header of an RSA public or private blob. It only checks that the blob has at least 8 bytes (otherwise EAtlasCryptoError); it does not check that the blob is an RSA key, so pass only keys from GenerateKeyPair.
Bits := TAtlasRsa.KeyBits(Pair.PublicKey);Examples
Wrap a content key and sign a release note
Prints 2048, TRUE for the unwrapped key and TRUE for the signature.
uses System.SysUtils, Atlas.Crypto, Atlas.CryptoBox, Atlas.CryptoKeys;
procedure RsaWrapAndSign;
var
Pair: TAtlasKeyPair;
ContentKey, Wrapped, Signature: TBytes;
begin
Pair := TAtlasRsa.GenerateKeyPair(2048);
try
WriteLn(TAtlasRsa.KeyBits(Pair.PublicKey));
ContentKey := TAtlasSecretBox.NewKey;
Wrapped := TAtlasRsa.Encrypt(Pair.PublicKey, ContentKey);
WriteLn(TAtlasBytes.ConstantTimeEquals(TAtlasRsa.Decrypt(Pair.PrivateKey, Wrapped), ContentKey));
Signature := TAtlasRsa.Sign(Pair.PrivateKey, TAtlasBytes.OfString('release 4.2'));
WriteLn(TAtlasRsa.Verify(Pair.PublicKey, TAtlasBytes.OfString('release 4.2'), Signature));
finally
Pair.Wipe;
TAtlasBytes.Wipe(ContentKey);
end;
end;
Related
TAtlasKeyPair · TAtlasSecretBox · TAtlasEcdsa