【问题标题】:javascript / golang RSA encrypt / verifyjavascript/golang RSA 加密/验证
【发布时间】:2017-06-18 11:17:24
【问题描述】:

我在客户端有以下 javascript

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')))

它的输出是

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

true

因此,使用该代码 sn-p 我可以签名并验证消息。 但是,我无法使用以下 Go sn-p 验证签名消息。

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)
}

已找到 sn-p 并根据其他答案进行了一些修改,但我无法使其工作。

【问题讨论】:

    标签: javascript go cryptography rsa digital-signature


    【解决方案1】:

    来自Node-RSA pages

    signingScheme — 用于签名和验证的方案。可以是'pkcs1''pss' 或'scheme-hash' 格式字符串(例如'pss-sha1')。 默认'pkcs1-sha256',或者,如果选择 pss:'pss-sha1'

    因此,NodeJS 实现使用带有 SHA-256 的 PKCS#1 v1.5 填充,而 Go 使用带有 SHA-256 的 PSS 填充。

    您基本上需要确保您的签名算法及其参数匹配。请注意,如果您选择 PSS 并且代码不断失败,您可能还需要确保用于 MGF1(PSS 中的掩码生成函数)的哈希函数匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-20
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 2018-06-07
      • 2018-09-15
      • 2017-06-20
      相关资源
      最近更新 更多