Must fOAEP padding go hand in hand for encryption and decryption? - encryption

Is it possible to Decrypt data using RSACryptoServiceProvider with fOAEP set to true if the data being decrypted does not conform to OAEP padded cipher text? i.e. fOAEP set to false for during data Encryption
public byte[] Decrypt(byte[] rgb, bool fOAEP);
Are there any Caveats to this scenario? Must fOAEP padding go hand in hand for encryption and decryption?

Related

AES Decryption in Solidity Contract

I am trying to create a solidity contract that decrypts a message using the an AES key. The data to be decrypted is saved as a variable in the contract (this data is already encrypted). The user should be able to pass an AES key into the decrypt function, this function should decrypt and return the message.
I do not mind the key being exposed on the network. Would there be any way to achieve this?
Solidity currently (v0.8) doesn't support any of the AES algorithms.
If your goal is to perform an action (e.g. transfer funds) to a user providing the correct key, you could have them calculate a keccak256 (one-way) hash of some secret (e.g. the key) off-chain, and then submit the original key for validation (against the hash stored in the contract).
pragma solidity ^0.8;
contract MyContract {
// keccak256 hash of the string "foo"
bytes32 hash = 0x41b1a0649752af1b28b3dc29a1556eee781e4a4c3a1f7f53f90fa834de098c4d;
function guessThePassword(string memory _password) external view returns (bool) {
return keccak256(abi.encodePacked(_password)) == hash;
}
}
Mind that this approach (as well as your original approach from the question) is vulnerable to frontrunning. One of the ways to prevent frontrunning, is to use double hashing. You can see a code example in this contract that was used for a competition type "first submitting the correct password can withdraw funds".

How do I encrypt a PGP message through java's crypto extension?

Currently I'm using bouncy castle's libraries for the actual work and have found an example at sloanseaman.com that (after a little tweaking) works with v1.52.
I've also got a working example from developer.com of how to use the JCE interface and can even drop the bcprov in it and use some of it's algorithms.
public class CryptoUtil {
private static final String ALGORITHM = "IDEA/PGP/NoPadding";
public static void encryptFile(File keyFile, File plainTextFile, File encryptedFile) throws GeneralSecurityException, IOException {
Cipher desCipher = Cipher.getInstance(ALGORITHM);
desCipher.init(Cipher.ENCRYPT_MODE, readKeyFromFile(keyFile));
OutputStream out = new BufferedOutputStream(new FileOutputStream(encryptedFile));
InputStream in = new BufferedInputStream(new FileInputStream(plainTextFile));
while (in.available() > 0) {
// Read the next chunk of bytes...
byte[] cleartextBytes = new byte[in.available()];
in.read(cleartextBytes);
// Now, encrypt them and write them to the encrypted file...
byte[] encryptedBytes = desCipher.update(cleartextBytes);
out.write(encryptedBytes, 0, encryptedBytes.length);
}
// Take care of any pending padding operations
out.write(desCipher.doFinal());
in.close();
out.flush();
out.close();
System.out.println("Encrypted to " + encryptedFile);
}
But no matter what algorithm string I use, I can't get my JCE utility to encrypt the way that the bouncyCastle utility does.
The furthest I've gotten is using "IDEA/PGP/NoPadding" which allows me to encrypt and decrypt within itself, but the BC utility won't decrypt them, saying there's an unknown object in the stream.
Here is my source code
Do you guys know what combination of Algorithm, Mode, and Padding I would need to use for this? Are there other options that I need to apply somehow? I guessing I need to use BC's version of AlgorithmParametersSpi but I haven't figured out how to create that yet
You can't. While OpenPGP uses "normal" public/private and symmetric encryption algorithms, trouble starts with the modes. OpenPGP uses its own mode (a modified CFB mode), and also the whole OpenPGP packet syntax is not supported by Java's default libraries.
You'd at least need to reimplement the OpenPGP CFB mode in Java, or somehow rely on Bouncy Castle's implementation.
The OpenPGP CFB mode already includes a replacement for the initialization vector; no additional padding is used/required.

outofmemoryexception when reading from smart card

I'm using .Net framework to develop an application that interact with Gemalto smart card (adding and retrieving),
I've successively done with the addition part, however when I try to read the data that I stored in the card I got an outOfMemoryException in the host application, can anyone figure out why does this happen?
this is the code in the host application that read from the card:
for (int i = 0; i < 5; i++)
{
try
{
string bookString = service.getBook(i);
}catch (Exception x) {
MessageBox.Show("an error occur");
}
}
and in app that is loaded on the card, I have this method:
public string getBook(int index)
{
return BookList[index].getBookID() + " , " + BookList[index].getBookDesc();
}
The Gemalto .NET Card contains both persistent memory and volatile
memory that are used for data storage. The persistent memory acts as
persistent storage for the card - data persists in it even after the
card is removed from a smart card reader. Volatile memory is reset
when the card loses power and cannot be used for persistent storage.
how you store your data, and how you fill the BookList with data ? please clarify more.
you have memory limitation of course, so you cannot store up to certain size, in this .net card you have 16KB of volatile memory (RAM) and 70KB of persistent memory (that contain assemblies, storage memory).
I tested in some Gemalto .net card and able to store 20KB of data in persistent storage memory, after that limit i get the same exception OutOfMemoryException (because the other 50KB is filled with files, assemblies).
This card is not designed to store database, records and so on, its used to store critical information like keys and passwords. So don't save more than this size and your code will be fine, or use any text compression algorithm (in the client application) to reduce the size before storage in card, but in the end don't try to store more than this ~XX KB.
update:
Because of this limitation you cannot store more than 70K in persistent storage, also you cannot retrieve more than 16KB from the card to client (because this data will be stored in local variable i.e volatile memory and then retrieved back to your client, and you have constrains also here).
So this is the source of your problem, you retrieve more than volatile memory can hold:
public string getBook(int index)
{
return bookList[index].getId() + " , " + bookList[index].getName();
}
before return value, this data will be in temporarily variable, and because you can't store more than 16KB you get the exception OutOfMemoryException.
the solution is to use this storage directly from the client (you have the reference so just use it):
public Book getTheBook(int index)
{
return bookList[index];
}
and from the client you can access Book functionality(make sure your Book is struct because marshalling is supported only for struct and primitive types in Gemalto .net card):
Console.WriteLine(service.getTheBook(0).getName());
You are attempting a task not typical for smart cards. Note, that cards have RAM in the range of a handful of kByte, to be divided between operating system and I/O buffer. The latter is unlikely to exceed 2 kByte (refer to the card manual for that) and even then you need to use extended length APDUs as mentioned in this answer. So the likely cause for your error is, that the data length exceeds the amount of RAM for the I/O buffer. While enlarging the buffer or using extended APDUs will stretch the limit, it is still easy to hit it with a really long description.
I got this exception only when attempting to retrieve long string (such as 100 words). I've done with adding part and that was accomplished by simply send a string of BookDesc.
public Book[] BookList=new Book[5];
public static int noOfBooks=0;
public string addBook(string bookDesc)
{
Book newBook=new Book();
newBook.setBookDesc(bookDesc);
newBook.setBookID(noOfBooks);
BookList[noOfBooks]=newBook;
noOfBooks++;
}

How to check why QCA DHPrivateKey did not create symetric key

I have program who exchange session key via Diffie-Hellman algorithm, or almost exchange. All action is 2 classes: one receives data and calculates private key, set it to second class, where symmetric key is calculated after receiving public part of DH.
Program is using Qt and QCA.
Private key is stored as widget class member:
QCA::DHPrivateKey m_localKey;
after receiving public part of other side key (as QByteArray) it calculates symetric key:
QCA::Initializer init;
QCA::DLGroup group(prime, p);
QCA::SecureArray remoteKey(m_remoteKey);
QCA::DHPublicKey pk(group, remoteKey);
m_sessionKey = m_localKey.deriveKey(pk);
but session key is always empty (m_sessionKey.isEmpty() and m_sessionKey.isNull() are true).
Values are set and they are exchange correct (remote part public key is received as it is),
m_localKey.isNull() and pk.isNull() returns correct values (false).
strange part is that when I run test, it works. Test use same order operations just private keys are created in one class, but logic to get symmetric key is same, and class used for that is same.
My question would be why it could behave different in test and separate programs. And is it possible to get any error/debug information from QCA::DHPrivateKey about what went wrong in deriveKey()?
Sadly that code was lost so can't check for sure, but problem probably was in 2 places - transfering/receiving data and too many QCA::Initializer calls.
After set QCA::Initializer in main and [re]writing data exchange code it works.
It's still sad that I don't know how check errors, if such occurs, so if anyone know please share these knowledges.

How can I increase the effectiveness of encryption for storing application settings?

I am currently using the RC4 algorithm to store application settings and when I observe output it looks easily decodable. The output of strings which start with the same letters appear to be the same.
Short strings lead to short output and longer strings produce longer output.
However I am looking for something that will produce longer output for short strings.
Is there another algorithm that will create more 'scrambled' output even with short strings?
I also want to suffix or prefix the input with some data that I can easily recognize and strip out after decoding to create more randomness on the output.
I have created new code using Rijndael displayed below, but it still suffers from the same lack of variation in the output. I suspect there are some additional parameters required to create more variation in the output, IVs, block padding and all that.
unit testform;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, DCPrijndael, DCPsha1;
type
{ TForm1 }
TForm1 = class(TForm)
edtKeyString: TEdit;
edtInputText: TEdit;
edtEncryptedText: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure edtInputTextChange(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{ TForm1 }
procedure TForm1.edtInputTextChange(Sender: TObject);
var
Cipher: TDCP_rijndael;
begin
Cipher:= TDCP_rijndael.Create(Self);
Cipher.InitStr(edtKeyString.Text,TDCP_sha1);
edtEncryptedText.Text := Cipher.EncryptString(edtInputText.Text);
Cipher.Burn;
Cipher.Free;
end;
initialization
{$I testform.lrs}
end.
RC4 is a stream cipher. You might want to look at a block cipher like AES. Don't forget to use padding, too, e.g. PKCS7.
EDIT: Do not add suffix/prefix data in order to "create more randomness". The encryption algorithm will do that for you (unless it's a broken algorithm, in which case choose a different one). At best this is pointless; at worst this is adding a "crib" that will make it easier for someone to attack your encryption.

Resources