隨着great help of the golang community,發現該溶液:
原始代碼張貼在http://play.golang.org/p/jrqN2KnUEM由Alex(見mailing list)。
如第8章規定的rfc2313我已經添加輸入塊大小檢查:http://play.golang.org/p/dGTl9siO8E
下面的代碼:
package main
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"math/big"
"os/exec"
)
var (
ErrInputSize = errors.New("input size too large")
ErrEncryption = errors.New("encryption error")
)
func PrivateEncrypt(priv *rsa.PrivateKey, data []byte) (enc []byte, err error) {
k := (priv.N.BitLen() + 7)/8
tLen := len(data)
// rfc2313, section 8:
// The length of the data D shall not be more than k-11 octets
if tLen > k-11 {
err = ErrInputSize
return
}
em := make([]byte, k)
em[1] = 1
for i := 2; i < k-tLen-1; i++ {
em[i] = 0xff
}
copy(em[k-tLen:k], data)
c := new(big.Int).SetBytes(em)
if c.Cmp(priv.N) > 0 {
err = ErrEncryption
return
}
var m *big.Int
var ir *big.Int
if priv.Precomputed.Dp == nil {
m = new(big.Int).Exp(c, priv.D, priv.N)
} else {
// We have the precalculated values needed for the CRT.
m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
m.Sub(m, m2)
if m.Sign() < 0 {
m.Add(m, priv.Primes[0])
}
m.Mul(m, priv.Precomputed.Qinv)
m.Mod(m, priv.Primes[0])
m.Mul(m, priv.Primes[1])
m.Add(m, m2)
for i, values := range priv.Precomputed.CRTValues {
prime := priv.Primes[2+i]
m2.Exp(c, values.Exp, prime)
m2.Sub(m2, m)
m2.Mul(m2, values.Coeff)
m2.Mod(m2, prime)
if m2.Sign() < 0 {
m2.Add(m2, prime)
}
m2.Mul(m2, values.R)
m.Add(m, m2)
}
}
if ir != nil {
// Unblind.
m.Mul(m, ir)
m.Mod(m, priv.N)
}
enc = m.Bytes()
return
}
func main() {
// o is output from openssl
o, _ := exec.Command("openssl", "rsautl", "-sign", "-inkey", "t.key", "-in", "in.txt").Output()
// t.key is private keyfile
// in.txt is what to encode
kt, _ := ioutil.ReadFile("t.key")
e, _ := ioutil.ReadFile("in.txt")
block, _ := pem.Decode(kt)
privkey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
encData, _ := PrivateEncrypt(privkey, e)
fmt.Println(encData)
fmt.Println(o)
fmt.Println(string(o) == string(encData))
}
更新:,我們可以期望有一個本地在Go 1.3中支持這種簽名,請參閱the appropriate commit。
這廚師API文檔是可悲的還不清楚,但我認爲你應該簽署頭,這意味着SignPKCS1v15可能是你想要的。 –
@GregS,遺憾的是,情況並非如此,我使用[mixlib-authentication sources](https://github.com/opscode/mixlib-authentication/blob/master/lib/mixlib/authentication/signedheaderauth)進行了雙重檢查。 RB#L94)。 – artyom
我想你可能是對的。我懷疑它使用的是PKCS1 v15 * block type 1 * padding,但是這對你沒有任何幫助。抱歉。 –