johninvictus

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

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

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:

  1. Read a PEM encoded certificate with a public key
  2. Encrypt a buffer of data (max 245 for PKCS1 padding)
  3. 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

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

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.

Where Next?

Popular in Questions Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&amp;query=perfume&amp;page=2, I would like to get: ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New

Other popular topics Top

axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48475 226
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54250 245
New

We're in Beta

About us Mission Statement