johninvictus
Please help me rewrite this Javascript function to Elixir
Hi Guys
Help me rewrite this Javascript function to Elixir.
security: function security() {
//sandbox value = Security Credential (Shortcode 1)
//production value = api initiator password
var bufferToEncrypt = new Buffer("Safaricom133!");
//read the sandbox/production certificate data
// PATH - e.g "./keys/sandbox-cert.cer"
var data = fs.readFileSync("PATH TO CERTIFICATE FILE");
//convert data to string
var privateKey = String(data);
//encrypt the credential using the privatekey
var encrypted = crypto.publicEncrypt({
key: privateKey,
padding: constants.RSA_PKCS1_PADDING
}, bufferToEncrypt);
//convert encrypted value to string and encode to base64
var securityCredential = encrypted.toString("base64");
//return value to invoking method
return securityCredential;
}
The certificate file looks something like this.
-----BEGIN CERTIFICATE-----
MIIGgDCCBWigAwIBAgIKMvrulAAAAARG5DANBgkqhkiG9w0BAQsFADBbMRMwEQYK
CZImiZPyLGQBGRYDbmV0MRkwFwYKCZImiZPyLGQBGRYJc2FmYXJpY29tMSkwJwYD
VQQDEyBTYWZhcmljb20gSW50ZXJuYWwgSXNzdWluZyBDQSAwMjAeFw0xNDExMTIw
NzEyNDVaFw0xNjExMTEwNzEyNDVaMHsxCzAJBgNVBAYTAktFMRAwDgYDVQQIEwdO
-----END CERTIFICATE-----
I have tried writing it but the task has proven to be tough.
Please help
Marked As Solved
cmkarlsson
It is hidden in the SubjectPublicKeyInfo, there should be a subjectPublicKey in there somewhere
{:SubjectPublicKeyInfo,
{:AlgorithmIdentifier, {1, 2, 840, 113549, 1, 1, 1}, <<5, 0>>},
<<48, 130, 1, 10, 2, 130, 1, 1, 0, 168, 183, 5, 117, 87, 21, 236, 119, 68,
58, 139, 108, 52, 186, 12, 62, 16, 251, 224, 37, 245, 122, 60, 220, 129,
243, 110, 136, ...>>}, :asn1_NOVALUE, :asn1_NOVALUE,
The <<48, 130, 1, 10 ...>> is the DER encoded public key I think. So then public_key:der_decode(:"RSAPublicKey", DerValue)
Also Liked
cmkarlsson
Assuming this is what you want. RSA with RSA_PKCS1_PADDING has known flaws which is exploitable though the Bleichenbacker’s CCA attack. The improved version claims to crack RSA with as little as 15,000 attempts (assuming it has access to an oracle of some sort).
Anyway what you are trying to do is:
- Read a PEM encoded certificate with a public key
- Encrypt a buffer of data (max 245 for PKCS1 padding)
- Base64 encode it.
You can use the public_key module to achieve this. From memory you do something like this:
def security(plaintext, certificate) do
#1) Decode the certificate. This assumes only one entry in the cert.
[pem_entry] = :public_key.pem_decode(certificate)
plk = :public_key.pem_entry_decode(pem_entry)
#2) Encrypt the plaintext
ciphertext = :public_key.encrypt_public(plaintext, plk, [{:rsa_pad, :rsa_pkcs1_padding}])
#3) Base64 encode and return the result
:base64.encode(ciphertext)
end
end
cmkarlsson
Great! I’d say the proper way to do it is to use the erlang records and access the information that way.
I’d define the Records in a separate module and then require them from the module where you want to use them.
Something like:
defmodule MyPublicKey.Records do
require Record
import Record, only: [defrecord: 2, extract: 2]
@public_key "public_key/include/public_key.hrl"
defrecord :"Certificate", extract(:Certificate, from_lib: @public_key)
defrecord :"TBSCertificate", extract(:TBSCertificate, from_lib: @public_key)
defrecord :"SubjectPublicKeyInfo", extract(:SubjectPublicKeyInfo, from_lib: @public_key)
end
defmodule MyPublicKey do
require MyPublicKey.Records
def extract_public_from_cert(certfile) do
cert_text = File.read!(certfile) |> String.trim()
[pem_entry] = :public_key.pem_decode(cert_text)
cert_decoded = :public_key.pem_entry_decode(pem_entry)
plk_der = cert_decoded
|> MyPublicKey.Records."Certificate"(:tbsCertificate)
|> MyPublicKey.Records."TBSCertificate"(:subjectPublicKeyInfo)
|> MyPublicKey.Records."SubjectPublicKeyInfo"(:subjectPublicKey)
:public_key.der_decode(:RSAPublicKey, plk_der)
end
end
cmkarlsson
Ok, this means that pem_entry_decode returns a certificate and not a public_key directly. You then need to extract the public_key from the certificate data structure. I have not got anything available to test this right now and can’t remember from heart.
The public key user guide might help you:
It is in erlang and they return erlang records, so you may want to read up on elixir Records as well to handle them in the proper way.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










