Using CA Certificate to execute Anaplan REST API 2.0 from VB .Net (C#)

Hello,

 

we had an application that calls the REST API 2.0 using Basic Auth. Now want to move to CA Certificate approach to get the Auth Token but we get 401 error.

 

we took as a reference the instructions in link below:

https://community.anaplan.com/t5/Best-Practices/Generating-Authentication-Strings-for-Using-CA-Certificates-with/ta-p/53403

 

we have the crt and key files.

 

has anyone done it in .net?

 

Thanks!

Best Answer

  • franciscoamores
    edited December 2022 Answer ✓

    Hi,

     

    I got it working. Let me share some hints:

     

    'Read CRT file content 
    Dim certStringContent As String = {File .crt content}

     

    'Authentication header -> Authorization: CACertificate {your_CA_certificate}
    '{you_CA_certificate} should be replaced by the contents of the public key (crt file)
    'This should include the contents between the "--- BEGIN CERTIFICATE ---" And "--- END CERTIFICATE ---" lines And Not including them
    authHeader = String.Format("CACertificate {0}", certStringContent.Replace(vbCr, "").Replace(vbLf, "").Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", ""))
    'Add header to list of headers
    listHeaders.Add(New KeyValuePair(Of String, String)("Authorization", authHeader))

     

    '*********************************************************
    'Create HTTP content for Cert Authentication (Get Token)
    '*********************************************************
    '{
    ' "encodedData" : "{encodedString}",
    ' "encodedSignedData" : "{signedString}"
    '}
    ' {encodedString} value should be a randomly generated base-64 encoded string of at least 100 bytes
    ' {signedString} value is the {encodedString} value that has been signed by the private key and then base-64 encoded.

    'Create a UnicodeEncoder to convert between byte array and string.
    Dim ByteConverter As New ASCIIEncoding

    '--------------------------------------------------------------------------------------
    ' Create Encoded String {encodedString}
    ' 1. Create Random String (100 bytes)
    ' 2. Encode With base64.
    '--------------------------------------------------------------------------------------

    'Create randmon string (This String will be signed By the Private key -> {signedString})
    Dim randomData As String = RandomString(100)
    'Encode random string with base64
    Dim encodedData As String = Convert.ToBase64String(ByteConverter.GetBytes(randomData))

    'Read Private key file content from dashboard parameters
    Dim privKeyStringContent As String = {File .key content}

    '--------------------------------------------------------------------------------------
    ' Create Encoded Signed String {signedString}
    ' 1. Sign the original random string
    ' 2. Encode With base64.
    '--------------------------------------------------------------------------------------

    'Create byte arrays to hold original and signed data
    Dim originalData As Byte() = ByteConverter.GetBytes(randomData)
    Dim signedData As Byte()

    'Create a RSA Crypto
    Dim rsaAlg As New RSACryptoServiceProvider
    'Private key in XML format
    Dim privKey As String = BRApi.Dashboards.Parameters.GetLiteralParameterValue(si, False, "prm_anaplan_privkey")

    'Read private key from XML string
    rsaAlg.FromXmlString(privKey)

    'Sign the original data (SHA512)
    signedData = rsaAlg.SignData(originalData, SHA512.Create())

    'Encode the signed data with base64
    Dim encodedSignedData As String = Convert.ToBase64String(signedData)

    'Build the JSON Body to get the token
    Dim jsonBodyAuth = New Dictionary(Of String, String) From
    {
    {"encodedData", encodedData},
    {"encodedSignedData", encodedSignedData}
    }
    'Serialize Json body (dictionary) as string
    Dim jsonAuthContent As String = JsonConvert.SerializeObject(jsonBodyAuth, Formatting.Indented)
    httpContent = New Http.StringContent(jsonAuthContent, Encoding.UTF8, "application/json")

Answers

  • anirudh
    edited December 2022
    Hi Francis,

    I have done this in Python. The process to generate an auth token using certificates goes this way:

    1. Create a random string (any number of characters) and sign your private key with the random string. This part has to be in the body of the request as json
    Json format:

    {'encodedData': <random string>,
    'encodedSignedData': <signed string>}

    2. The request also has to have an authorization header like so:
    {'AUTHORIZATION': 'CACertificate ' + <public key>}
    where the public key is the block of text between BEGIN CERTIFICATE and END CERTIFICATE in your public key file (open in notepad to view it in text)

    3. Send this request to 'https://auth.anaplan.com/token/authenticate' and you should receive an auth token

    Let me know if you need more help

    Regards,
    Anirudh
  • franciscoamores
    edited December 2022

    Hello,

     

    The Pyhon code is in the doc but I was looking more for the VB .net code.

    Just to make sure i'm doing in the right way

     

    Thanks

  • Kipetcoff
    edited December 2022

    Hello, I'm trying to convert your code to c# and don't undestand this BRApi.Dashboards.Parameters.GetLiteralParameterValue(si, False, "prm_anaplan_privkey").

    Which API did you use? How did you get anaplan key in XML format? I have private key in text format, how can I use it?

    2020-12-16_10-11-22.png

  • franciscoamores
    edited December 2022

    Yes,

     

    forget about that one. That's an internal API of our software to read the private key from a parameter. The key is in the same format as you show so you can read it from a file

  • Kipetcoff
    edited December 2022

    Ok and how does this API generate XML? What is the source? Private key is in text format.

  • Kipetcoff
    edited December 2022

    I found the solution, I used https://superdry.apphb.com/tools/online-rsa-key-converter online service to convert PEM key to XML format. Thank you for VB idea.

  • dan999
    edited December 2022

    I went through this nightmare getting things working with .net core 3.1. So for anyone who is interested and experiencing a similar challenge, i've created a gist you can all reference here:

     

    https://gist.github.com/dbardouh/5e23ce80a6b62830c4dc8445316b18d6

     

    This method will return the authentication token you can use in subsequent API requests in Anaplan.

     

    I hope this helps someone.

  • gowtham9394
    edited December 2022
    Can you share the python code .?