I am currently working on a encryption and decryption service for my application, using Google Tink.
The problem is the following: I want to program it without using (nearly) duplicate code and therefore I had the idea of using generics.
If parsing the Strings to a byte[] is the only option I will be doing that, but I’d rather not.
These are the methods & variables:
The 3 Stacks I am using:
private Stack<String> plaintextAccInformation = new Stack<>(); private Stack<byte[]> encryptedAccInformation = new Stack<>(); private Stack<String> decryptedAccInformation = new Stack<>();
The method, used to get the information from the Stack (which I wanted to solve with generics and also is not working). No. Parsing does not work, as the method has to be accessible with two different datatypes.
private <T> Account getInformation(Stack<T> stack) { boolean isApproved = stack.peek(); stack.pop(); boolean isAdmin = stack.peek(); stack.pop(); double balance = stack.peek(); stack.pop(); String password = stack.peek(); stack.pop(); String iBan = stack.peek(); stack.pop(); String uuid = stack.peek(); stack.pop(); return new Account(uuid, iBan, password, balance, isAdmin, isApproved); }
The method used to encrypt all the data of an Account object.
The idea is to iterate through the “`Stack plaintextAccInformation“` and encrypt every variable in the Account object and then save each encrypted variable to a new “`Stack encryptedAccInformation“`
public Account encrypt(Account account) throws GeneralSecurityException { this.plaintextAccInformation.empty(); this.encryptedAccInformation.empty(); agjEncryption = new AesGcmJce(key.getBytes()); this.plaintextAccInformation.push(account.getUuid()); this.plaintextAccInformation.push(account.getIban()); this.plaintextAccInformation.push(account.getPassword()); this.plaintextAccInformation.push(String.valueOf(account.getBalance())); this.plaintextAccInformation.push(String.valueOf(account.isAdmin())); this.plaintextAccInformation.push(String.valueOf(account.isApproved())); Iterator<String> iterator = plaintextAccInformation.iterator(); while (iterator.hasNext()) { encryptedAccInformation.push(agjEncryption.encrypt(plaintextAccInformation.peek().getBytes(), aad.getBytes())); plaintextAccInformation.pop(); } return getInformation(this.encryptedAccInformation); }
The method used to decrypt the variables saved in the “`Stack encryptedAccInformation“` and save it to the “`Stack decryptedAccInformation“`
public Account decrypt() throws GeneralSecurityException { this.decryptedAccInformation.empty(); this.agjDecryption = new AesGcmJce(key.getBytes()); Iterator<byte[]> iterator2 = encryptedAccInformation.iterator(); while (iterator2.hasNext()) { decryptedAccInformation.push(new String(agjDecryption.decrypt(encryptedAccInformation.peek(), aad.getBytes()))); encryptedAccInformation.pop(); } return getInformation(this.decryptedAccInformation); }
Advertisement
Answer
Assuming you’re sure the stack will always be in the order you expect here (which you seem to be).
Instead of a generic stack (which I believe limits you to only one value of T), you could use a stack of Object
and cast the results of the peek()
function.
private Account getInformation(Stack<Object> stack) { Boolean isApproved = (Boolean) stack.peek(); stack.pop(); Boolean isAdmin = (Boolean) stack.peek(); stack.pop(); Double balance = (Double) stack.peek(); stack.pop(); String password = (String) stack.peek(); stack.pop(); String iBan = (String) stack.peek(); stack.pop(); String uuid = (String) stack.peek(); stack.pop(); return new Account(uuid, iBan, password, balance, isAdmin, isApproved); }