Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RSA and AES encryption/decryption capabilities to crypto stdlib #13422

Merged
merged 44 commits into from
Feb 12, 2019

Conversation

ayomawdb
Copy link
Member

Purpose

Ballerina crypto stdlib does not have functions to support encryption. This PR adds AES and RSA encryption capabilities to stdlib with common cipher modes and padding schemes.

Resolves: #9054

Examples

RSA Encryption

The sample given below shows how to use encryption function encryptRsaEcb and decryption function decryptRsaEcb to perform RSA encryption and decryption.

import ballerina/io;
import ballerina/crypto;
import ballerina/encoding;

public function main() returns error? {
     // Input value for cryto operations
     string input = "Hello Ballerina";
     byte[] inputArr = input.toByteArray("UTF-8");

     crypto:KeyStore keyStore = { path: "/home/ballerina/keystore.p12", password: "ballerina" };

     // Public key used for encryption
     crypto:PublicKey publicKey = check crypto:decodePublicKey(keyStore = keyStore, keyAlias = "ballerina");

     // Private key used for decryption
     crypto:PrivateKey privateKey = check crypto:decodePrivateKey(keyStore = keyStore, keyAlias = "ballerina",
                                                            keyPassword = "ballerina");


     // Encrypt and decrypt input value using RSA ECB PKCS1 padding.
     byte[] output = check crypto:encryptRsaEcb(inputArr, publicKey);
     output = check crypto:decryptRsaEcb(output, privateKey);
     io:println("RSA ECB PKCS1 decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using RSA ECB OAEPwithSHA512andMGF1 padding.
     output = check crypto:encryptRsaEcb(inputArr, publicKey, padding = crypto:OAEPwithSHA512andMGF1);
     output = check crypto:decryptRsaEcb(output, privateKey, padding = crypto:OAEPwithSHA512andMGF1);
     io:println("RSA ECB OAEPwithSHA512andMGF1 decrypted value: " + encoding:byteArrayToString(output));
}

AES Encryption

The sample given below shows how to use encryption function encryptAesCbc and decryption function decryptAesCbc to perform AES encryption and decryption.

import ballerina/io;
import ballerina/crypto;
import ballerina/encoding;
import ballerina/math;

public function main() returns error? {
     // Input value for cryto operations
     string input = "Hello Ballerina!";
     byte[] inputArr = input.toByteArray("UTF-8");

     // Randomly generate a 128 bit key
     byte[16] keyArr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
     foreach var i in 0...15 {
        keyArr[i] = check byte.convert(math:randomInRange(0, 255));
     }

     // Randomly generate a 128 bit IV
     byte[16] ivArr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
     foreach var i in 0...15 {
        ivArr[i] = check byte.convert(math:randomInRange(0, 255));
     }

     // Encrypt and decrypt input value using AES CBC PKCS5 padding
     byte[] output = check crypto:encryptAesCbc(inputArr, keyArr, ivArr);
     output = check crypto:decryptAesCbc(output, keyArr, ivArr);
     io:println("AES CBC PKCS5 decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using AES CBC no padding
     output = check crypto:encryptAesCbc(inputArr, keyArr, ivArr, padding = crypto:NONE);
     output = check crypto:decryptAesCbc(output, keyArr, ivArr, padding = crypto:NONE);
     io:println("AES CBC no padding decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using AES GCM PKCS5 padding
     output = check crypto:encryptAesGcm(inputArr, keyArr, ivArr);
     output = check crypto:decryptAesGcm(output, keyArr, ivArr);
     io:println("AES GCM PKCS5 decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using AES GCM no padding
     output = check crypto:encryptAesGcm(inputArr, keyArr, ivArr, padding = crypto:NONE);
     output = check crypto:decryptAesGcm(output, keyArr, ivArr, padding = crypto:NONE);
     io:println("AES GCM no padding decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using AES ECB PKCS5 padding
     output = check crypto:encryptAesEcb(inputArr, keyArr);
     output = check crypto:decryptAesEcb(output, keyArr);
     io:println("AES ECB PKCS5 decrypted value: " + encoding:byteArrayToString(output));

     // Encrypt and decrypt input value using AES ECB no padding
     output = check crypto:encryptAesEcb(inputArr, keyArr, padding = crypto:NONE);
     output = check crypto:decryptAesEcb(output, keyArr, padding = crypto:NONE);
     io:println("AES ECB no padding decrypted value: " + encoding:byteArrayToString(output));
}

@codecov-io
Copy link

codecov-io commented Jan 31, 2019

Codecov Report

Merging #13422 into master will increase coverage by 0.36%.
The diff coverage is 85%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master   #13422      +/-   ##
============================================
+ Coverage     63.98%   64.34%   +0.36%     
+ Complexity      659      426     -233     
============================================
  Files          2147     2152       +5     
  Lines         94210    94515     +305     
  Branches      12406    12471      +65     
============================================
+ Hits          60281    60818     +537     
+ Misses        29035    28794     -241     
- Partials       4894     4903       +9
Impacted Files Coverage Δ Complexity Δ
...llerinalang/stdlib/crypto/nativeimpl/HashSha1.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...alang/stdlib/encoding/nativeimpl/DecodeBase64.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...ang/stdlib/crypto/nativeimpl/DecodePrivateKey.java 57.14% <ø> (-1%) 0 <0> (ø)
...erinalang/stdlib/crypto/nativeimpl/HmacSha256.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...erinalang/stdlib/crypto/nativeimpl/HashSha256.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...nalang/stdlib/crypto/nativeimpl/SignRsaSha256.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...lang/stdlib/crypto/nativeimpl/DecodePublicKey.java 67.74% <ø> (-1.01%) 0 <0> (ø)
...rinalang/stdlib/encoding/nativeimpl/DecodeHex.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...llerinalang/stdlib/crypto/nativeimpl/HmacSha1.java 100% <ø> (ø) 0 <0> (ø) ⬇️
...rg/ballerinalang/stdlib/encoding/EncodingUtil.java 91.3% <ø> (ø) 0 <0> (ø) ⬇️
... and 101 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c0bc10...ada50ff. Read the comment docs.

examples/crypto/crypto.bal Outdated Show resolved Hide resolved
examples/crypto/crypto.bal Outdated Show resolved Hide resolved
examples/crypto/crypto.bal Outdated Show resolved Hide resolved
examples/crypto/crypto.bal Outdated Show resolved Hide resolved
examples/crypto/crypto.bal Outdated Show resolved Hide resolved
stdlib/crypto/src/main/ballerina/crypto/Module.md Outdated Show resolved Hide resolved
stdlib/crypto/src/main/ballerina/crypto/Module.md Outdated Show resolved Hide resolved
stdlib/crypto/src/main/ballerina/crypto/Module.md Outdated Show resolved Hide resolved
stdlib/crypto/src/main/ballerina/crypto/Module.md Outdated Show resolved Hide resolved
Shan Mahanama and others added 15 commits February 11, 2019 09:27
@ayomawdb ayomawdb merged commit 4163f85 into ballerina-platform:master Feb 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants