http://www.ascdi.com/blockchain-transaction-authentication-and-security/
OCTOBER 6, 2017 BY AMY RALLS
Rahul Padole onOctober 4, 2017
In the blockchain world, data distribution to all trust less entities and immutability are the major advantages in terms of building transparency in transactions. Then what about the transactions happening between entities who want to maintain secrecy or need authentication so that only intended entity/recipient will be able to understand it?
Blockchain platforms available across have developed various security features to handle the transaction anonymity and security. Hyperledger Fabric does the provisioning for identity management as well as transaction authentication via certificate authority (CA). Ethereum platform supports transaction authentication using transaction signing mechanism where transaction can be signed by an author using the secured key (private key). But challenge here is how the intended recipient will identify this transaction and verify the authenticity? How do we share the transaction to intended recipient by ensuring its authenticity?
Ethereum in conjunction with Java Web3J provides API to perform transaction signing where the author signs the transaction with his own secret key and generates transaction hash.
RawTransaction rawTxn=RawTransaction.createEtherTransaction(param1, param2,…,));
byte[] signedMessage = TransactionEncoder.signMessage(rawTxn, privateKey/credentials);
Once signed, transaction can be executed and hash can be generated. How we share this hash to intended recipient is a challenge. Also making this transaction hash secure is the key for transaction authentication process. I have used smart contract to share the hash with intended recipient. Before sharing the hash in a smart contract I added one more security layer to hash the transaction, by encrypting it using Java crypto AES encryption utility. This ensures added level of data security to transaction hash.
Cipher aesCipher = Cipher.getInstance(“AES”);
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedTxnHash = aesCipher.doFinal(transactionHash);
The encrypted transaction hash (hash of hash) then push to a smart contract which has been permissioned for intended recipients. The intended recipient will be authenticated first and later he will be provided access to the transaction hash.
contract GetTransactionHashForAuthenticUser {
address[] intendedRcptAddrs = [0x45df89ghf6dft4n5kl56rt, 0xgh234g78jk90sdf4ghh23];
addressownerAddr= 0x87eaf79c12e96a3dc6f53426c;
function fetchTransactionHash() public return (string)
{
uint i = 0;
for(i = 0; i < addrs.length; ++i)
if(msg.sender == addrs[i])
// To do –Return stored hash of hash for authenticated user.
return “hashOfHash“;
else
return “You are not an authorised user“;
}
}
The overall process looks like:
Once intended user is authenticated and gets the required hash from the above contract, then using steps given below, he can obtain the exact transaction hash and later decode/decrypt the signed transaction.
Cipher aesCipher = Cipher.getInstance(“AES”);
aesCipher.init(Cipher.DECRYPT_MODE, secretKey);
byte [] bytePlainText = aesCipher.doFinal(byteCipherText);
return new String(bytePlainText);
Please note that secret key can be generated using Java crypto API and shared with intended user in an offline process. After decrypting the transaction hash we need to decode the signed transaction for authentication. Once we decode the signed transaction we get the sender and receiver addresses for transaction verification. I keep the transaction decode process as a part of solidity smart contract where I used solidityecrecoverfunction to recover the transaction to get the owner of the transaction. If owner/sender and receiver from decode process is valid then we can assume that transaction is authenticated. Solidityecrecover function call looks like this:
ecrecover (txnHash, uint8(v), r, s);
We can obtain r, s and v values using Java web3j API from transaction signature as follows:
Transaction tx = new Transaction(rawtxHashHexByteArray);
java.math.BigInteger rInitial = tx.getSignature().r;
java.math.BigInteger sInitial = tx.getSignature().s;
byte vInitial = tx.getSignature().v
Based on r, s and v value pass to a smart contract function ecrecover, it will return you transaction owner/sender address.
The above entire process ensures transaction authentication and security by sharing the transaction hash in a secured way with additional security mechanism (hash of hash) for robust transaction processing.