Last active
August 9, 2023 08:18
-
-
Save karmats/4270441be5a34fff7062 to your computer and use it in GitHub Desktop.
RSA encryption with public key in salesforce apex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public with sharing class RsaEncryption { | |
private String modulus; | |
private String exponent; | |
// Hex digits | |
private static final String DIGITS = '0123456789abcdef'; | |
private static final Decimal HEX_BASE = 16; | |
public RsaEncryption(String modulus, String exponent) { | |
this.modulus = modulus; | |
this.exponent = exponent; | |
} | |
public String encrypt(String input) { | |
Blob mod = EncodingUtil.base64Decode(modulus); | |
Blob exp = EncodingUtil.base64Decode(exponent); | |
// Pad password.nonce | |
Blob pn = Blob.valueOf(String.fromCharArray(pkcs1Pad2(input, mod.size() - 1))); | |
Decimal modDec = hexToDecimal(EncodingUtil.convertToHex(mod)); | |
Decimal expDec = hexToDecimal(EncodingUtil.convertToHex(exp)); | |
Decimal pnDec = hexToDecimal(EncodingUtil.convertToHex(pn)); | |
// Calcluate padded^exp % mod and convert to hex | |
Decimal result = modPow(pnDec, expDec, modDec); | |
String hexResult = decimalToHex(result); | |
// If length is uneven, add an extra 0 | |
if ((hexResult.length() & 1) == 1) { | |
hexResult = '0' + hexResult; | |
} | |
// Generate the data to be encrypted. | |
Blob encodedData = EncodingUtil.convertFromHex(hexResult); | |
return EncodingUtil.base64Encode(encodedData); | |
} | |
@testVisible | |
private static Decimal hexToDecimal(String hex) { | |
Decimal result = 0; | |
integer length = hex.length(); | |
integer i = 0; | |
while(i < length) { | |
integer hexByte = DIGITS.indexOf(hex.substring(i, i + 1).toLowerCase()); | |
i++; | |
result += hexByte * HEX_BASE.pow(length - i); | |
} | |
return result; | |
} | |
@testVisible | |
private static String decimalToHex(Decimal d) { | |
String hex = ''; | |
while (d > 0) { | |
Decimal digit = modulus(d, HEX_BASE); // rightmost digit | |
hex = DIGITS.substring(digit.intValue(), digit.intValue() + 1) + hex; // string concatenation | |
d = d.divide(16, 0, RoundingMode.FLOOR); | |
} | |
return hex; | |
} | |
// base^exp % mod | |
@testVisible | |
private static Decimal modPow(Decimal base, Decimal exp, Decimal mod) { | |
if (base < 1 || exp < 0 || mod < 1) { | |
return -1; | |
} | |
Decimal result = 1; | |
while (exp > 0) { | |
if ((exp.longValue() & 1) == 1) { | |
result = modulus((result * base), mod); | |
} | |
base = modulus((base * base), mod); | |
exp = exp.divide(2, 0, RoundingMode.FLOOR); | |
} | |
return result; | |
} | |
// dividend % divisor | |
@testVisible | |
private static Decimal modulus(Decimal dividend, Decimal divisor) { | |
Decimal d = dividend.divide(divisor, 0, RoundingMode.FLOOR); | |
return dividend - (d * divisor); | |
} | |
// Pad using PKCS#1 v.2. See https://en.wikipedia.org/wiki/PKCS_1 | |
// s = String to pad | |
// n = bytes to fill must be bigger than s.length() | |
@testVisible | |
private static List<integer> pkcs1Pad2(String s, integer n) { | |
// Byte array | |
List<integer> ba = new List<integer>(); | |
// Fill array with zeros to get the right size | |
for(integer i = 0; i < n; i++) { | |
ba.add(0); | |
} | |
integer i = s.length() - 1; | |
while(i >= 0 && n > 0) { | |
ba.set(--n, s.charAt(i--)); | |
} | |
ba.set(--n, 0); | |
while(n > 2) { // random non-zero pad | |
// Since the array is converted to a string, choose integers that corresponds | |
// to a proper char code see http://www.asciitable.com | |
integer rnd = Math.round(Math.random() * (127 - 32) + 32); | |
ba.set(--n, rnd); | |
} | |
ba.set(--n, 2); | |
ba.set(--n, 0); | |
return ba; | |
} | |
} |
I took the gist(s) like that one I implemented RSA OAEP SHA-256 based on it. It has few shell scripts to generate keys and prepare them to be used with Apex. It has a test class with example of how to be used. Hope it will be helpful for the community. One thing to remember is that it takes a lot of CPU for 4K RSA OAEP SHA256 decryption.
https://github.com/alex-shekhter/apex-crypto-rsa-oaep-sha256
If I have an RSA public key, how do I get the modulus and exponent? Has anyone successfully implemented RSA public key encryption with this code?
openssl rsa -pubin -inform PEM -text -noout < YOUR_PUBLIC_KEY_IN_PEM_FORMAT
can i get them in apex code ?
Yes you can.
Take a look at the
https://github.com/mattandneil/apex-rsa-sha-512/blob/master/CryptoRsaSha512.cls
Inner class Asn will allow you to obtain modulus and public exponent from
the PEM file.
Good luck
…On Tue, Aug 8, 2023 at 10:19 PM rickywgr ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
can i get them in apex code ?
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/karmats/4270441be5a34fff7062#gistcomment-4655649>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB4RMCCXTFFMKRIFX7D6O2LXULXSHBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVAZTCNZRG43DSOFHORZGSZ3HMVZKMY3SMVQXIZI>
.
You are receiving this email because you commented on the thread.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
Thanks, I'll spend some time looking into it !
At 2023-08-09 16:12:23, "alex-shekhter" ***@***.***> wrote:
@alex-shekhter commented on this gist.
Yes you can.
Take a look at the
https://github.com/mattandneil/apex-rsa-sha-512/blob/master/CryptoRsaSha512.cls
Inner class Asn will allow you to obtain modulus and public exponent from
the PEM file.
Good luck
On Tue, Aug 8, 2023 at 10:19 PM rickywgr ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
can i get them in apex code ?
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/karmats/4270441be5a34fff7062#gistcomment-4655649>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AB4RMCCXTFFMKRIFX7D6O2LXULXSHBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVAZTCNZRG43DSOFHORZGSZ3HMVZKMY3SMVQXIZI>
.
You are receiving this email because you commented on the thread.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
—
Reply to this email directly, view it on GitHub or unsubscribe.
You are receiving this email because you commented on the thread.
Triage notifications on the go with GitHub Mobile for iOS or Android.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not so simple to understand how to use this code. You need to have 2 parameters : modulus and exponent.
Do you have a example explaining the format for these parameters ?