How to sign a message in JAVA and verify it in GO

Source: Internet
Author: User
Tags begin rsa private key
This is a creation in Article, where the information may have evolved or changed. In my company, we use Java and Go as the development platform, and of course sometimes these projects interact with each other. In this article, I want to introduce our solution for message signing on the Java side and validating it in the Go service program. First, let's talk about the following architecture, where our Java application runs on a new virtual machine instance in the cloud, and the underlying image instance contains a small Go service program. This service is the main portal of our configuration management system, we do not want to have from untrusted clients can modify the node. The two-way SSL that contains the signature in the request appears to be sufficient to trust the client. But since both of these components are open source, we don't have any "secrets" in the binaries, so we chose the RSA asymmetric key pair to generate and verify the signature. The Java side has a private key, and the Go side has a public key. Java is an ancient platform (individuals have many years of Java experience) so Java has a lot of libraries, but I started using go. I don't have a sixth sense, but I think Go should be the weakest in the list of supported protocols. The good news is that Go has a built-in Crypto/rsa software package, and the bad news is that it only supports pkcs#1. During the study, I discovered a third-party library that supported Pkcs#8, and we had to stop at the program point and focus on: 1. Using a well-tested library 2 built on older standards. Using the Unknown library pkcs#1 on the new standard is not the latest standard version, but on the other hand third-party libraries look too risky. So we chose the first option. In the business, we have such a library, which has only one function, that is to verify the PSS (random signature scheme) signature through the VERIFYPSS function. "' Gofunc checksignature (rawsign string, Pubpem []byte, data []byte] Error {var err errorvar sign []bytevar pub interface{ }sign, err = base64. Stdencoding.decodestring (rawsign) if err! = Nil {return Err}block, _: = Pem. Decode (PUBPEM) if block = = Nil {return errors. New ("Failed to decode public PEM")}pub, err = x509. Parsepkixpublickey (bLock. Bytes) If err! = Nil {return Err}newhash: = crypto. SHA256. New () newhash.write (data) OPTs: = RSA. PSSOPTIONS{SALTLENGTH:20}//Java default Salt Lengtherr = RSA. VERIFYPSS (pub. ( *rsa. PublicKey), Crypto. SHA256, Newhash.sum (nil), sign, &opts) return err} ' on the Java side, the client places an extra head into the request that contains the request principal signature generated with the private key. The next step is to find the signature and invoke the previously implemented functionality. "' Gofunc Wrap (Handler func (w http. Responsewriter, req *http. Request), Signaturekey []byte] http. Handler {return HTTP. Handlerfunc (Func (w http. Responsewriter, R *http. Request) {Body: = new (bytes. Buffer) defer r.body.close () ioutil. ReadAll (IO. Teereader (R.body, Body)) R.body = Ioutil. Nopcloser (body)//We read the subject two times, we must wrap the original readclosersignature: = Strings. Trimspace (R.header.get ("signature")) If Err: = Checksignature (signature, Signaturekey, body. Bytes ()); Err! = Nil {//Error Handlingw. Writeheader (http. statusnotacceptable) W.write ([]byte ("406 Not Acceptable")) return}http. Handlerfunc (handler). Servehttp (W, R)})} "finally implements the HTTP handler and wraps it together with the officer program. "' Gofunc Postithandler (w http. ResponsewrITER, req *http. Request) {W.write ([]byte ("OK"))}func Registerhandler () {signature, _: = Ioutil. ReadFile ("/path/of/public/key") r: = Mux. Newrouter () r.handle ("/postit", Wrap (Postithandler, signature)). Methods ("POST") http. Handle ("/", R) http. Listenandserve ("8080", nil)} "I have written unit tests to make sure that the checksum is in accordance with the design. "' Gotype testwriter struct {header http. Headerstatus intmessage String}func (w *testwriter) Header () http. Header {return W.header}func (w *testwriter) Write (b []byte) (int, error) {w.message = string (b) return Len (b), Nil}func (w *testwriter) Writeheader (s int) {w.status = S}func testwrapallvalid (t *testing. T) {PK, _: = RSA. GenerateKey (Rand. Reader, 1024x768) Pubder, _: = X509. Marshalpkixpublickey (&PK. PublicKey) Pubpem: = Pem. Encodetomemory (&pem. Block{type: "Public KEY", Headers:nil, Bytes:pubder}) Content: = "Body" newhash: = Crypto. SHA256. New () Newhash.write ([]byte (content)) OPTs: = RSA. Pssoptions{saltlength:20}sign, _: = RSA. SIGNPSS (Rand. Reader, PK, crypto. SHA256, Newhash.sum (nil), &opts) Body: = bytes. Newbufferstring (content) Req, _: = http. Newrequest ("GET", "Http://valami", body) req. Header.add ("signature", base64. Stdencoding.encodetostring (sign)) Writer: = new (testwriter) Writer.header = req. HeaderHandler: = Wrap (func (w http. Responsewriter, req *http. Request) {}, Pubpem) handler. Servehttp (writer, req) if writer.status! = 0 {T.errorf ("writer.status 0 = =%d", writer.status)} "" It looks like we've finished the service-side implementation, Now let's write some Java code. I've researched how to generate PSS signatures in Java, and I've discovered that one of our dependencies already contains the functionality we need. [Bouncy Castle Crypto API] (http://bouncycastle.org/), a very well-known library in the Java world, it is very simple to apply. "' c//PRIVATEKEYPEM-PEM format private key//data-signature data public static string Generatesignature (String Privatekeypem, byte[] data) {T Ry (Pemparser pemparser = new Pemparser (new StringReader (Clarifypemkey))) {Privatekeypem Pemkeypair = ( Pemkeypair) Pemparser.readobject (); Keyfactory factory = keyfactory.getinstance ("RSA"); X509encodedkeyspec Publickeyspec = new X509encodedkeyspec (Pemkeypair.getpublickeyinfo (). getEncoded ()); PublicKey PublicKey = Factory.generatepublic (Publickeyspec); Pkcs8encodedkeyspec Privatekeyspec = new Pkcs8encodedkeyspec (Pemkeypair.getprivatekeyinfo (). getEncoded ()); Privatekey Privatekey = factory.generateprivate (Privatekeyspec); KeyPair KP = new KeyPair (PublicKey, Privatekey); Rsaprivatekeyspec Privkeyspec = Factory.getkeyspec (Kp.getprivate (), rsaprivatekeyspec.class); Psssigner signer = new Psssigner (new Rsaengine (), New Sha256digest (), 20); Make sure that we use the default salt Lenghtsigner.init (True, new Rsakeyparameters (True, Privkeyspec.getmodulus (), Privkeyspec.getprivateexponent ())); Signer.update (data, 0, data.length); byte[] signature = Signer.generatesignature ( ); return baseencoding.base64 (). Encode (signature);} catch (NoSuchAlgorithmException | IOException | invalidkeyspecexception | Cryptoexception e) {throw new RuntimeException (e);}} private static string Clarifypemkey (String Rawpem) {return "-----BEGIN RSA PRIVATE KEY-----\ n" + rawpem.replaceall ("----- (. *)-----|\n "," ") +" \ n-----END RSA PRIVATE KEY-----"; PemparsEr nem kedveli a sortöréseket} "that's the way ... PS: I don't show you how to use Java to generate key pairs, because you can find a lot of knowledge about it online.

Via:https://mhmxs.blogspot.hk/2018/03/how-to-sign-messages-in-java-and-verify.html

Author: Richárd Kovács Translator: fredvence proofreading: polaris1119

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

372 Reads
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.