I want to use a hybrid encryption scheme for file encryption. The scheme must use PKCS#1 v1.5 – which is vulerable to padding oracle attacks – because many smartcards (e.g. the OpenPGP Card) only support PKCS#1 v1.5.
So I came up with the following scheme (the RSA-keys are 4096-bit large, the symmetric algorithm is either AES-256-CTR or ChaCha-20 with 256bit keys and of course different keys for signing and encrypting are used. And of course I know that for stream-ciphers absolutely unique IVs must be used with the same key):
Encryption:
var privateSigningKey;
var publicEncryptionKey;
--- var encryptedBlock = encryptAsym(sessionKey, iV) + encryptSym(data + hash(data));
+++ var encryptedBlock = encryptAsym(sessionKey, iV) + encryptSym(data + sign(data));
var signatureBlock = sign(encryptedBlock);
var encryptedData = encryptedBlock + signatureBlock;
return encryptedData;
Decryption:
var trustedPublicKeys[];
var signatureBlock = encryptedData.getSignatureBlock();
var encryptedBlock = encryptedData.getEncryptedBlock();
var sender = "";
for each trustedPublicKey do {
bool signatureValid = verifySignature(encryptedBlock, signatureBlock, trustedPublicKeys[i].getSigningKey();
if (signatureValid) sender = trustedPublicKeys[i].getName();
}
if (sender == "") exit("Untrusted signature; stopping to prevent padding oracle attacks.");
var plainDataBlock = decryptHybrid(encryptedBlock);
--- var hash = plainDataBlock.getHash();
+++ var signature = plainDataBlock.getHash();
var plainData = plainDataBlock.getPlainData();
--- if (hash != hash(plainData)) exit("Decryption failed.");
+++ if (signature != sign(plainData)) exit("Decryption failed; untrusted signature.");
return plainData;
Can this scheme considered to be secure? Or are there any security issues or better alternatives?
I know that you usually don't roll your own crypto; but I cannot use the OpenPGP format because it doesn't prevent padding attacks (look at this question) and I don't know any better alternative.
Edit: Scheme updated