0

I know that REST APIs are used a lot and are very important to web, but I've mostly only ever done standalone desktop type stuff (think single player game developer). I've done a lot of research recently and have found the REST concept to be straightforward, but my current project is my first time ever using a REST API, or cryptography in any meaningful capacity. So if I say something stupid, please bear with me.

In my current project, I am trying to send email from my Unity3D application using the Google Cloud Platform (GCP) Gmail REST API. I found in my initial implementation using google's client libraries (which they recommend that developers use--and for good reason) that google's client libraries create malformed REST requests when used within the context of Unity3D (why this is remains TBD).

As a result, I am attempting to do all of my interaction with GCP via raw REST requests (over HTTP). I have constructed a Json Web Token as outlined here (the best reference I have found so far).

The token has a header (as described in the above article) and a claims set (also in the article). I have also managed to generate a signature, but I'm pretty sure that my signature is incorrect--because I am creating the signature without ever loading my Service Account credentials from the JSON credential file that I downloaded from the GCP control panel.

My big question is "How do I do this":

Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google API Console. The output will be a byte array.

in C#? I currently have the UTF-8 representation stored as a byte[] called "InputBuffer", but I'm having a really hard time figuring out how to sign the InputBuffer with the private key. Could someone please provide an example with an explanation? or provide a link to such? (I think I found one link in my whole search, but forgot to bookmark it and ended up losing it. (Edit: Found it here, although it is a Python example that uses jwt.encode, I'm trying to intentionally reinvent the wheel here in C# so that I can work around the Google Library bugs as Unity is not a supported platform.)

What form do I need to get the private key into? Byte[]? String? DISCLAIMER: This is for a production project, so I need to make sure I understand this properly and that my implementation is secure. What mistakes should I watch out for?

EDIT: Found this SO question which essentially encapsulates what I am trying to do, however SOUser Hans. Z points out that it is vulnerable to a security attack. I am trying to do the same thing as the author of the previous question, but do it properly.

Jason
  • 628
  • 3
  • 10
Brandon S.
  • 306
  • 1
  • 4
  • 14
  • The first item is which cryptography library do you plan to use? This affects the code that you need to write. You mention that you do not want to use libraries, but Google has already written the code for you. Study the client source code. In any event, you need to use a crypto library such as BouncyCastle or IdentityModel. If nobody else posts an answer, I can provide code that I have written. I support a number of crypto libraries. I wrote this article which shows the same steps but in Python: https://www.jhanley.com/google-cloud-creating-oauth-access-tokens-for-rest-api-calls/ – John Hanley Jan 28 '20 at 03:14
  • Yes John! Thanks for your comment. I have read your article and found it very useful, but unfortunately insufficient to answer my current question. I'm not familiar at all with IdentityModel or BouncyCastle, but I have been trying to use the Microsoft Cryptography API (CAPI) to create the signature. Would this be sufficient to do something similar to BouncyCastle? – Brandon S. Jan 28 '20 at 03:50
  • 1
    The Microsoft crypto library is also good. BouncyCastle is one of the more popular C# libraries. I will write another article like the one I did using Python but using C#. Watch my website for the new article. – John Hanley Jan 28 '20 at 04:14
  • @JohnHanley Hey John, Brandon were you guys able to do it in C# with updated code? If yes, could you please share the link. I'd love to learn how you guys implemented it. Thanks – Shubh77 Dec 10 '21 at 02:16

0 Answers0