duanhoupeng6642 2017-06-18 11:17
浏览 128
已采纳

javascript / golang RSA加密/验证

I have the following javascript on the client

var NodeRSA = require('node-rsa');

var ClientSide = new NodeRSA({ b: 512 });
var privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAj1IEeouqDYiMX0rMiPAI64UntzNxE01+tB+k+aKesHzVXE5A
GnyWHIFdrByfjR93CMh3y56xsL78VP1/Xp8iVmAnbiFN5kpmawJ1owhDvNIl8A+Q
UiDzMg0z/yepzjp61Dg4CUFzGrmTfYO1aMWyWhR0ZKfy+HvVaGjpod2ioScU7Fkz
eO+fDR85quLFta7OXDwqD4NCPYeZTS5fgK1Nn72nrItoj5e36fzWvZntfvi4NHt7
nqOj4VH5e5YJHvmLWHh5Swh+OVyIAwhxYSK5PSupicGG8ixVy75hkjzZ2vW5JdVW
MPYbVUMpqjtE+i1zQTYNJ36hM/zznZR/drU7UwIDAQABAoIBAHvs02qTMWuaUqZj
KxCNXWkpLfo/RNsH+zMM2b3xW34HswWps8wzRilHwxN7fIquVmMF1HAAvGyz98QV
nfjXaP1/DxkvOwiR9JU6/zUFhGzU2XEGRCh/zUnOGNPcG/vynRq7sdhu+3R0WpAB
Pu9lYp55aVtPzcwGZ7VsYfhQiLsGnJ5GkBS7z4P3aG29By6fGnTwR83iQHtR5SvQ
Rb/xJxZjTM00OZ2ssAtw24Hu8QXTuOAHdy2B5E1tsF+hVHs4iB0OiLzW7m4GBkb/
/og76ouB4G+j6IjG2E5TO0eAdslKn2w3dZRgqnVDF5CPtRdbAc83xOwSouuuqN26
FPsLkwECgYEA4Jyf3j9UzW0znnOcul4MDvfKuMCzD/5wnc24aYBbie4Joi/jqDbc
9J5jqyfgzdqwjxiwkEFJi7gBcclO1i1SoIfA6ooVoJeQlzdMpSytZVhzgE2aJO1E
ORP7kLimAHysjMJ27Fix1VRZltcZe0E9DErkw/hoPemAMvDvW2myyaECgYEAo1k7
iS4O9GSHUKvbEJWR5r+9Qvv4aObOaRFRDfq4/E9fZwujzKAvxwkGFXjxwpzxKJqN
paVEL2cWY+S46f4B501xgnNknuf6po8ZEaXD5vy281xoU4YX1KFySbV8eXGmkyiO
M2+vPGrsTGOIsKnQW8jmaxWTClbSdPoLWfwzqHMCgYAS/Kp2+xuMEgMfDd7d0j1q
tn+ohoGchIG4lT9Vi8gxLLIbx7iS67BZ7Vm3ijNys13hetDSIPK6oN9eYwoLCOHH
ODKSoQGbBbTvU3ljLRerTYLWAblaDcSKnqnRXgqKV/+uFnI/IHBH/E1mduBsjuM+
OsaD2mfVc/umUr+pFpJKgQKBgCeaTb3fhc6oxMnBMLZfnOT13Zvs3PgJ5UdB5IXg
IJNDZxzjjI3i1FKMFIaGMQ7+39T5S5g6bkKT2rDTViWc6Lc8ZmW7Nkz0byeMkAZg
SxOod26fG8gMPaDWl4/ZSVlkPX92GKvNyw152tpWU2CJezOVjI+vxlt+Wz3zFWd2
psuTAoGAbdlzYFK+7e2ru8fdbVk9SBLn9cnPdDCx+wgJV7dB0zzSh1oqIrE766Mx
c9wBIKWNqNEsFsFI4ejuMRdC4Hyc6ecCNea3nj3BHCS70V0p1MtFII6SpADDqBTW
3ZnLfcN2MiFDBXVqNkCsMcqd8KVdzEqEy1JDplmW84OpfQu88ms=
-----END RSA PRIVATE KEY-----`
var publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj1IEeouqDYiMX0rMiPAI
64UntzNxE01+tB+k+aKesHzVXE5AGnyWHIFdrByfjR93CMh3y56xsL78VP1/Xp8i
VmAnbiFN5kpmawJ1owhDvNIl8A+QUiDzMg0z/yepzjp61Dg4CUFzGrmTfYO1aMWy
WhR0ZKfy+HvVaGjpod2ioScU7FkzeO+fDR85quLFta7OXDwqD4NCPYeZTS5fgK1N
n72nrItoj5e36fzWvZntfvi4NHt7nqOj4VH5e5YJHvmLWHh5Swh+OVyIAwhxYSK5
PSupicGG8ixVy75hkjzZ2vW5JdVWMPYbVUMpqjtE+i1zQTYNJ36hM/zznZR/drU7
UwIDAQAB
-----END PUBLIC KEY-----`

ClientSide.importKey(privateKey, 'pkcs1');
let result = ClientSide.sign('test_message', 'base64')

console.log(result)

var serverSide = new NodeRSA({ b: 512 });
serverSide.importKey(publicKey, 'pkcs8-public');
console.log(serverSide.verify('test_message', new Buffer(result, 'base64')))

And the output for it is

baU/46UJYUp6Xt6sYs306t1vQdUOBRg10YuJPKspwLYj3aJHMgeQXMSfvBKvS+PJ3CMSVMVVjvoweNRu7A6ZzCSyVub9+qv0u5/2vSdUqiLDSHP5Gj9CRxsWPTLnapS27CJh3ywhqfgkuOSt6RZYTXqqoraHMP2jmGjfdLQmJbPiWamOc20u7xeTHK8oRmpXV0Pi5w4+7E6CkyfF9EfpLmmGGYiKqOWriWhYFbqkp+OV7FY4WRN1KwtmcZcnlWZ/4wAzg9uDL+8ZGyWKq62JY6Ee8LO5u6FCG7lU3KqBdq4eFKYI3CM9wdrxoZ7kNUlq0tQGZQ++MihdZQOfwj1vSA==

true

So with that code snippet I'm able to sign and verify the message. However, I'm not able to verify the signed message with the following Go snippet.

package main

import (
  "crypto"
  "crypto/rsa"
  "crypto/x509"
  "encoding/base64"
  "encoding/pem"
  "errors"
  "fmt"
  "os"
)

func main() {

  toSign := "test_message"

  signed, err := base64.StdEncoding.DecodeString("baU/46UJYUp6Xt6sYs306t1vQdUOBRg10YuJPKspwLYj3aJHMgeQXMSfvBKvS+PJ3CMSVMVVjvoweNRu7A6ZzCSyVub9+qv0u5/2vSdUqiLDSHP5Gj9CRxsWPTLnapS27CJh3ywhqfgkuOSt6RZYTXqqoraHMP2jmGjfdLQmJbPiWamOc20u7xeTHK8oRmpXV0Pi5w4+7E6CkyfF9EfpLmmGGYiKqOWriWhYFbqkp+OV7FY4WRN1KwtmcZcnlWZ/4wAzg9uDL+8ZGyWKq62JY6Ee8LO5u6FCG7lU3KqBdq4eFKYI3CM9wdrxoZ7kNUlq0tQGZQ++MihdZQOfwj1vSA==")
  if err != nil {
    println("unable do decode")
    os.Exit(1)
  }

  parser, err := loadPublicKey()
  if err != nil {
    println("unable to load public key")
    os.Exit(1)
  }

  err = parser.Unsign([]byte(toSign), signed)
  if err != nil {
    println("unable to verify")
    os.Exit(1)
  }

}

func loadPublicKey() (Unsigner, error) {

  return parsePublicKey([]byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj1IEeouqDYiMX0rMiPAI
64UntzNxE01+tB+k+aKesHzVXE5AGnyWHIFdrByfjR93CMh3y56xsL78VP1/Xp8i
VmAnbiFN5kpmawJ1owhDvNIl8A+QUiDzMg0z/yepzjp61Dg4CUFzGrmTfYO1aMWy
WhR0ZKfy+HvVaGjpod2ioScU7FkzeO+fDR85quLFta7OXDwqD4NCPYeZTS5fgK1N
n72nrItoj5e36fzWvZntfvi4NHt7nqOj4VH5e5YJHvmLWHh5Swh+OVyIAwhxYSK5
PSupicGG8ixVy75hkjzZ2vW5JdVWMPYbVUMpqjtE+i1zQTYNJ36hM/zznZR/drU7
UwIDAQAB
-----END PUBLIC KEY-----`))
}

func parsePublicKey(pemBytes []byte) (Unsigner, error) {
  block, _ := pem.Decode(pemBytes)
  if block == nil {
    return nil, errors.New("ssh: no key found")
  }

  var rawkey interface{}
  switch block.Type {
  case "PUBLIC KEY":
    rsa, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
      return nil, err
    }
    rawkey = rsa
  default:
    return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
  }

  return newUnsignerFromKey(rawkey)
}

type Unsigner interface {
  // Sign returns raw signature for the given data. This method
  // will apply the hash specified for the keytype to the data.
  Unsign(data []byte, sig []byte) error
}

func newUnsignerFromKey(k interface{}) (Unsigner, error) {
  var sshKey Unsigner
  switch t := k.(type) {
  case *rsa.PublicKey:
    sshKey = &rsaPublicKey{t}
  default:
    return nil, fmt.Errorf("ssh: unsupported key type %T", k)
  }
  return sshKey, nil
}

type rsaPublicKey struct {
  *rsa.PublicKey
}

func (r *rsaPublicKey) Unsign(message []byte, sig []byte) error {
  var opts rsa.PSSOptions
  opts.SaltLength = rsa.PSSSaltLengthAuto
  PSSmessage := message
  newhash := crypto.SHA256
  pssh := newhash.New()
  pssh.Write(PSSmessage)
  hashed := pssh.Sum(nil)
  return rsa.VerifyPSS(r.PublicKey, newhash, hashed, sig, &opts)
}

The snippet was found and a little bit modified from other answers, however I can't make it work.

  • 写回答

1条回答 默认 最新

  • dongqun9403 2017-06-18 11:44
    关注

    From the Node-RSA pages:

    signingScheme — scheme used for signing and verifying. Can be 'pkcs1' or 'pss' or 'scheme-hash' format string (eg 'pss-sha1'). Default 'pkcs1-sha256', or, if chosen pss: 'pss-sha1'.

    So the NodeJS implementation uses PKCS#1 v1.5 padding with SHA-256 while Go uses PSS padding with SHA-256.

    You basically need to make sure that your signature algorithms and their parameters match. Note that you may also want to make sure that the hash function used for MGF1 (the mask generation function within PSS) matches if you go for PSS and the code keeps failing.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!