//VerifySignature verifies the signature of a message func (rsaKey *RsaKey) VerifySignature(message string, signature string) (err error) { hashAlgorithm := crypto.SHA256 if rsaKey.privateKey == nil { err = errors.New("privateKey is nil") return } messageBytes := bytes.NewBufferString(message) //hash pssh := hashAlgorithm.New() pssh.Write(messageBytes.Bytes()) messageHash := pssh.Sum(nil) var signatureBytes []byte signatureBytes, err = base64.StdEncoding.DecodeString(signature) if err != nil { return } //Verify signature var opts rsa.PSSOptions opts.SaltLength = rsa.PSSSaltLengthAuto err = rsa.VerifyPSS(&rsaKey.privateKey.PublicKey, hashAlgorithm, messageHash, signatureBytes, &opts) return }
func (m *Msg) Message(fromkey *rsa.PublicKey, dstkey *rsa.PrivateKey) (data []byte, err error) { hash := crypto.SHA256 data = make([]byte, 0) for i, d := range m.Data { plainText, err := rsa.DecryptOAEP(hash.New(), rand.Reader, dstkey, d, []byte("")) if err != nil { return nil, e.Push(err, "can't decrypt the message") } pssh := hash.New() pssh.Write(plainText) hashed := pssh.Sum(nil) var opts rsa.PSSOptions opts.SaltLength = rsa.PSSSaltLengthAuto err = rsa.VerifyPSS(fromkey, hash, hashed, m.Signature[i], &opts) if err != nil { return nil, e.Push(err, "can't verify the signature") } data = append(data, plainText...) } return data, nil }
func NewMsg(from, to string, fromkey *rsa.PrivateKey, tokey *rsa.PublicKey, data []byte) (*Msg, error) { hash := crypto.SHA256 max := tokey.N.BitLen()/8 - 2*hash.Size() - 2 num := len(data) / max if len(data)%max > 0 { num++ } msg := &Msg{ From: from, To: to, Data: make([][]byte, num), Signature: make([][]byte, num), } j := 0 for i := 0; i < len(data); i += max { end := i + max if end > len(data) { end = len(data) } ciphertex, err := rsa.EncryptOAEP(hash.New(), rand.Reader, tokey, data[i:end], []byte("")) if err != nil { return nil, e.Push(err, "can't encrypt message") } pssh := hash.New() pssh.Write(data[i:end]) hashed := pssh.Sum(nil) var opts rsa.PSSOptions opts.SaltLength = rsa.PSSSaltLengthAuto signature, err := rsa.SignPSS(rand.Reader, fromkey, hash, hashed, &opts) if err != nil { return nil, e.Push(err, "can't sign the message") } msg.Data[j] = ciphertex msg.Signature[j] = signature j++ } return msg, nil }
//Sign creates the signature for a message func (rsaKey *RsaKey) Sign(message string) (signature string, err error) { var signatureBytes []byte hashAlgorithm := crypto.SHA256 messageBytes := bytes.NewBufferString(message) //hash hasher := hashAlgorithm.New() hasher.Write(messageBytes.Bytes()) messageHash := hasher.Sum(nil) //sign var pssOptions rsa.PSSOptions pssOptions.SaltLength = saltSize pssOptions.Hash = hashAlgorithm signatureBytes, err = rsa.SignPSS(rand.Reader, rsaKey.privateKey, hashAlgorithm, messageHash, &pssOptions) if err != nil { return } signature = base64.StdEncoding.EncodeToString(signatureBytes) return }
func main() { // Generate RSA Keys miryanPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { fmt.Println(err.Error) os.Exit(1) } miryanPublicKey := &miryanPrivateKey.PublicKey raulPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { fmt.Println(err.Error) os.Exit(1) } raulPublicKey := &raulPrivateKey.PublicKey fmt.Println("Private Key : ", miryanPrivateKey) fmt.Println("Public key ", miryanPublicKey) fmt.Println("Private Key : ", raulPrivateKey) fmt.Println("Public key ", raulPublicKey) //Encrypt Miryan Message message := []byte("the code must be like a piece of music") label := []byte("") hash := sha256.New() ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, raulPublicKey, message, label) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Printf("OAEP encrypted [%s] to \n[%x]\n", string(message), ciphertext) fmt.Println() // Message - Signature var opts rsa.PSSOptions opts.SaltLength = rsa.PSSSaltLengthAuto // for simple example PSSmessage := message newhash := crypto.SHA256 pssh := newhash.New() pssh.Write(PSSmessage) hashed := pssh.Sum(nil) signature, err := rsa.SignPSS(rand.Reader, miryanPrivateKey, newhash, hashed, &opts) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Printf("PSS Signature : %x\n", signature) // Decrypt Message plainText, err := rsa.DecryptOAEP(hash, rand.Reader, raulPrivateKey, ciphertext, label) if err != nil { fmt.Println(err) os.Exit(1) } fmt.Printf("OAEP decrypted [%x] to \n[%s]\n", ciphertext, plainText) //Verify Signature err = rsa.VerifyPSS(miryanPublicKey, newhash, hashed, signature, &opts) if err != nil { fmt.Println("Who are U? Verify Signature failed") os.Exit(1) } else { fmt.Println("Verify Signature successful") } }