In my company, we use Java and Go as our development platforms and of course, sometimes those projects have to communicate with each other. In the current blog post, I would like to introduce our solution to sign messages on the Java side and verify them in a Go service.
First, let's talk a bit about architecture. Our Java application spins up new virtual machines in the cloud, and the base image of the instance contains a small Go service. That service is the main entry point of our configuration management system, and we don't want to allow any operation from untrusted clients to modify nodes. Two-way SSL with a signature in the request sounded fair enough to trust in clients. Both components are open source, we don't have any "secret" in the binaries, so we elected RSA asymmetric key pairs to generate and verify signatures. Java has the private key and Go has the public one. Time to go deeper.
Java is an old platform (personally I have many years of experience with it), has many libraries on the topic, so I started with Go. I don't have a sixth sense, but I felt that Go should be the weakest in the list of supported protocols. The good news is, Go has a built-in crypto/rsa package, the bad news is it supports only PKCS#1. During the research, I found a 3rd party library with PKCS#8 support and we had to stop and weigh at this point of the planning:
Back in business, we have the library, which has only one option namely the VerifyPSS function to verify PSS (Probabilistic signature scheme) signatures.
On Java side, the client puts an extra header into the request, which contains the signature of the request's body, generated with the private key. The next step is to find the signature and call the function implemented previously.
Lastly, implement the HTTP handler and wrap it with the verifier.
I wrote a unit test to be sure the verification works as designed.
Seems we are ready with the service side of the implementation, let's write some Java code. I researched how to generate PSS signatures in Java, and I found that one of our dependencies already contains the required feature. Bouncy Castle Crypto API is a well-known library in the Java world and it was straightforward to apply it.
That's it...
ps: I don't want to bore you with how to generate key pairs in Java, you can find many options on the Internet.
First, let's talk a bit about architecture. Our Java application spins up new virtual machines in the cloud, and the base image of the instance contains a small Go service. That service is the main entry point of our configuration management system, and we don't want to allow any operation from untrusted clients to modify nodes. Two-way SSL with a signature in the request sounded fair enough to trust in clients. Both components are open source, we don't have any "secret" in the binaries, so we elected RSA asymmetric key pairs to generate and verify signatures. Java has the private key and Go has the public one. Time to go deeper.
Java is an old platform (personally I have many years of experience with it), has many libraries on the topic, so I started with Go. I don't have a sixth sense, but I felt that Go should be the weakest in the list of supported protocols. The good news is, Go has a built-in crypto/rsa package, the bad news is it supports only PKCS#1. During the research, I found a 3rd party library with PKCS#8 support and we had to stop and weigh at this point of the planning:
- built-in well-tested library with older standards
- unknown package with newer standards.
Back in business, we have the library, which has only one option namely the VerifyPSS function to verify PSS (Probabilistic signature scheme) signatures.
On Java side, the client puts an extra header into the request, which contains the signature of the request's body, generated with the private key. The next step is to find the signature and call the function implemented previously.
Lastly, implement the HTTP handler and wrap it with the verifier.
I wrote a unit test to be sure the verification works as designed.
Seems we are ready with the service side of the implementation, let's write some Java code. I researched how to generate PSS signatures in Java, and I found that one of our dependencies already contains the required feature. Bouncy Castle Crypto API is a well-known library in the Java world and it was straightforward to apply it.
That's it...
ps: I don't want to bore you with how to generate key pairs in Java, you can find many options on the Internet.