Black Lives Matter. Support the Equal Justice Initiative.

Package rsa

import "crypto/rsa"
Overview
Index
Examples

Overview ▾

软件包rsa实施PKCS#1中指定的RSA加密.

RSA是一个基本操作,在此程序包中用于实现公用密钥加密或公用密钥签名.

使用RSA进行加密和签名的原始规范是PKCS#1,默认情况下,术语" RSA加密"和" RSA签名"是指PKCS#1版本1.5. 但是,该规范存在缺陷,如果可能,新设计应使用第二版,通常仅由OAEP和PSS调用.

该软件包中包含两组接口. 当不需要更抽象的接口时,可以使用v1.5 / OAEP进行加密/解密以及使用v1.5 / PSS进行签名/验证的功能. 如果需要通过公钥原语进行抽象,则PrivateKey结构可从crypto包中实现Decrypter和Signer接口.

此软件包中的RSA操作未使用固定时间算法实现.

Index ▾

Constants
Variables
func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)
func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)
func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error
func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)
func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)
func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)
func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) ([]byte, error)
func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error
func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error
type CRTValue
type OAEPOptions
type PKCS1v15DecryptOptions
type PSSOptions
    func (pssOpts *PSSOptions) HashFunc() crypto.Hash
type PrecomputedValues
type PrivateKey
    func GenerateKey(random io.Reader, bits int) (*PrivateKey, error)
    func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error)
    func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)
    func (priv *PrivateKey) Precompute()
    func (priv *PrivateKey) Public() crypto.PublicKey
    func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
    func (priv *PrivateKey) Validate() error
type PublicKey
    func (pub *PublicKey) Size() int

Package files

pkcs1v15.go pss.go rsa.go

Constants

const (
    // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
    // as possible when signing, and to be auto-detected when verifying.
    PSSSaltLengthAuto = 0
    // PSSSaltLengthEqualsHash causes the salt length to equal the length
    // of the hash used in the signature.
    PSSSaltLengthEqualsHash = -1
)

Variables

ErrDecryption表示解密消息失败. 避免自适应攻击是故意含糊的.

var ErrDecryption = errors.New("crypto/rsa: decryption error")

尝试加密对于公钥大小而言太大的消息时,返回ErrMessageTooLong.

var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")

ErrVerification表示无法验证签名. 避免自适应攻击是故意含糊的.

var ErrVerification = errors.New("crypto/rsa: verification error")

func DecryptOAEP

func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error)

DecryptOAEP使用RSA-OAEP解密密文.

OAEP由用作随机预言机的哈希函数进行参数化. 给定消息的加密和解密必须使用相同的哈希函数,并且sha256.New()是一个合理的选择.

随机参数(如果不为nil)用于使私钥操作失效,并避免定时进行边信道攻击. 盲法纯属此功能的内部–随机数据不必与加密时使用的数据匹配.

label参数必须与加密时给定的值匹配. 有关详细信息,请参见EncryptOAEP.

Example

Code:

ciphertext, _ := hex.DecodeString("4d1ee10e8f286390258c51a5e80802844c3e6358ad6690b7285218a7c7ed7fc3a4c7b950fbd04d4b0239cc060dcc7065ca6f84c1756deb71ca5685cadbb82be025e16449b905c568a19c088a1abfad54bf7ecc67a7df39943ec511091a34c0f2348d04e058fcff4d55644de3cd1d580791d4524b92f3e91695582e6e340a1c50b6c6d78e80b4e42c5b4d45e479b492de42bbd39cc642ebb80226bb5200020d501b24a37bcc2ec7f34e596b4fd6b063de4858dbf5a4e3dd18e262eda0ec2d19dbd8e890d672b63d368768360b20c0b6b8592a438fa275e5fa7f60bef0dd39673fd3989cc54d2cb80c08fcd19dacbc265ee1c6014616b0e04ea0328c2a04e73460")
label := []byte("orders")

// crypto/rand.Reader is a good source of entropy for blinding the RSA
// operation.
rng := rand.Reader

plaintext, err := DecryptOAEP(sha256.New(), rng, test2048Key, ciphertext, label)
if err != nil {
    fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
    return
}

fmt.Printf("Plaintext: %s\n", string(plaintext))

// Remember that encryption only provides confidentiality. The
// ciphertext should be signed before authenticity is assumed and, even
// then, consider that messages might be reordered.

func DecryptPKCS1v15

func DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)

DecryptPKCS1v15使用RSA和PKCS#1 v1.5中的填充方案对纯文本进行解密. 如果rand!= nil,则使用RSA盲法来避免定时侧信道攻击.

请注意,此函数是否返回错误会泄露机密信息. 如果攻击者可以使此功能重复运行,并了解每个实例是否返回错误,则他们可以解密和伪造签名,就好像它们具有私钥一样. 有关解决此问题的方法,请参见DecryptPKCS1v15SessionKey.

func DecryptPKCS1v15SessionKey

func DecryptPKCS1v15SessionKey(rand io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error

DecryptPKCS1v15SessionKey使用RSA和PKCS#1 v1.5中的填充方案解密会话密钥. 如果rand!= nil,则使用RSA盲法来避免定时侧信道攻击. 如果密文长度错误或密文大于公共模数,则返回错误. 否则,不会返回任何错误. 如果填充有效,则将产生的纯文本消息复制到密钥中. 否则,密钥不变. 这些替代方案会在固定时间内发生. 希望该功能的用户预先生成一个随机会话密钥,并使用结果值继续执行协议. 这将消除攻击者可以了解有关纯文本的任何信息的可能性. 请参阅"基于RSA加密标准PKCS#1的针对协议的选择的密文攻击",Daniel Bleichenbacher,加密技术进展(Crypto '98).

请注意,如果会话密钥太小,则攻击者可能会强行使用它. 如果他们能够做到这一点,那么他们就可以了解是否使用了随机值(因为相同的密文会有所不同),以及填充是否正确. 这使该功能失去意义. 使用至少16个字节的密钥可以防止这种攻击.

Example

RSA只能加密非常有限的数据量. 为了加密合理数量的数据,通常使用混合方案:RSA用于加密对称原语(例如AES-GCM)的密钥. 在加密之前,通过将数据嵌入已知结构来"填充"数据. 这样做有多种原因,但最明显的是要确保该值足够大,以使幂运算大于模数. (否则,可以使用平方根解密.)在这些设计中,当使用PKCS#1 v1.5时,至关重要的是避免透露接收到的RSA消息是否格式正确(即解密的结果是否正确).是正确填充的消息),因为这会泄漏机密信息. DecryptPKCS1v15SessionKey专为这种情况而设计,并在包含随机密钥的缓冲区中恒定时间复制解密的对称密钥(如果格式正确). 因此,如果RSA结果格式不正确,则实现将在恒定时间内使用随机密钥.

Code:

// crypto/rand.Reader is a good source of entropy for blinding the RSA
// operation.
rng := rand.Reader

// The hybrid scheme should use at least a 16-byte symmetric key. Here
// we read the random key that will be used if the RSA decryption isn't
// well-formed.
key := make([]byte, 32)
if _, err := io.ReadFull(rng, key); err != nil {
    panic("RNG failure")
}

rsaCiphertext, _ := hex.DecodeString("aabbccddeeff")

if err := DecryptPKCS1v15SessionKey(rng, rsaPrivateKey, rsaCiphertext, key); err != nil {
    // Any errors that result will be “public” – meaning that they
    // can be determined without any secret information. (For
    // instance, if the length of key is impossible given the RSA
    // public key.)
    fmt.Fprintf(os.Stderr, "Error from RSA decryption: %s\n", err)
    return
}

// Given the resulting key, a symmetric scheme can be used to decrypt a
// larger ciphertext.
block, err := aes.NewCipher(key)
if err != nil {
    panic("aes.NewCipher failed: " + err.Error())
}

// Since the key is random, using a fixed nonce is acceptable as the
// (key, nonce) pair will still be unique, as required.
var zeroNonce [12]byte
aead, err := cipher.NewGCM(block)
if err != nil {
    panic("cipher.NewGCM failed: " + err.Error())
}
ciphertext, _ := hex.DecodeString("00112233445566")
plaintext, err := aead.Open(nil, zeroNonce[:], ciphertext, nil)
if err != nil {
    // The RSA ciphertext was badly formed; the decryption will
    // fail here because the AES-GCM key will be incorrect.
    fmt.Fprintf(os.Stderr, "Error decrypting: %s\n", err)
    return
}

fmt.Printf("Plaintext: %s\n", string(plaintext))

func EncryptOAEP

func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error)

EncryptOAEP使用RSA-OAEP加密给定的消息.

OAEP由用作随机预言机的哈希函数进行参数化. 给定消息的加密和解密必须使用相同的哈希函数,并且sha256.New()是一个合理的选择.

随机参数用作熵的来源,以确保两次加密同一封邮件不会产生相同的密文.

label参数可以包含不会加密的任意数据,但是会为消息提供重要的上下文. 例如,如果给定的公钥用于解密两种类型的消息,则可以使用不同的标签值来确保攻击者无法将用于一种目的的密文用于另一种目的. 如果不需要,可以为空.

消息的长度不得超过公共模数的长度减去哈希长度的两倍,再减去2.

Example

Code:

secretMessage := []byte("send reinforcements, we're going to advance")
label := []byte("orders")

// crypto/rand.Reader is a good source of entropy for randomizing the
// encryption function.
rng := rand.Reader

ciphertext, err := EncryptOAEP(sha256.New(), rng, &test2048Key.PublicKey, secretMessage, label)
if err != nil {
    fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
    return
}

// Since encryption is a randomized function, ciphertext will be
// different each time.
fmt.Printf("Ciphertext: %x\n", ciphertext)

func EncryptPKCS1v15

func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)

EncryptPKCS1v15使用RSA和PKCS#1 v1.5中的填充方案对给定消息进行加密. 该消息的长度不得超过公共模数的长度减去11个字节.

rand参数用作熵的来源,以确保两次加密同一封邮件不会产生相同的密文.

WARNING: use of this function to encrypt plaintexts other than session keys is dangerous. Use RSA OAEP in new protocols.

func SignPKCS1v15

func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)

SignPKCS1v15使用来自RSA PKCS#1 v1.5的RSASSA-PKCS1-V1_5-SIGN计算散列的签名. 请注意,散列必须是使用给定散列函数对输入消息进行散列的结果. 如果hash为零,则将对hash进行直接签名. 除了互操作性之外,这是不可取的.

如果rand不为零,则将使用RSA盲法来避免定时侧信道攻击.

此功能是确定性的. 因此,如果可能的消息集很小,则攻击者可能能够构建从消息到签名的映射并标识已签名的消息. 与以往一样,签名提供的是真实性,而不是机密性.

Example

Code:

// crypto/rand.Reader is a good source of entropy for blinding the RSA
// operation.
rng := rand.Reader

message := []byte("message to be signed")

// Only small messages can be signed directly; thus the hash of a
// message, rather than the message itself, is signed. This requires
// that the hash function be collision resistant. SHA-256 is the
// least-strong hash function that should be used for this at the time
// of writing (2016).
hashed := sha256.Sum256(message)

signature, err := SignPKCS1v15(rng, rsaPrivateKey, crypto.SHA256, hashed[:])
if err != nil {
    fmt.Fprintf(os.Stderr, "Error from signing: %s\n", err)
    return
}

fmt.Printf("Signature: %x\n", signature)

func SignPSS 1.2

func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) ([]byte, error)

SignPSS使用RSASSA-PSS [1]计算散列的签名. 请注意,散列必须是使用给定散列函数对输入消息进行散列的结果. opts参数可以为nil,在这种情况下,使用合理的默认值.

func VerifyPKCS1v15

func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error

VerifyPKCS1v15验证RSA PKCS#1 v1.5签名. hashed是使用给定的hash函数对输入消息进行哈希处理的结果,而sig是签名. 通过返回nil错误指示有效签名. 如果hash为零,则直接使用hash. 除了互操作性之外,这是不可取的.

Example

Code:

message := []byte("message to be signed")
signature, _ := hex.DecodeString("ad2766728615cc7a746cc553916380ca7bfa4f8983b990913bc69eb0556539a350ff0f8fe65ddfd3ebe91fe1c299c2fac135bc8c61e26be44ee259f2f80c1530")

// Only small messages can be signed directly; thus the hash of a
// message, rather than the message itself, is signed. This requires
// that the hash function be collision resistant. SHA-256 is the
// least-strong hash function that should be used for this at the time
// of writing (2016).
hashed := sha256.Sum256(message)

err := VerifyPKCS1v15(&rsaPrivateKey.PublicKey, crypto.SHA256, hashed[:], signature)
if err != nil {
    fmt.Fprintf(os.Stderr, "Error from verification: %s\n", err)
    return
}

// signature is a valid signature of message from the public key.

func VerifyPSS 1.2

func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error

VerifyPSS验证PSS签名. hashed是使用给定的hash函数对输入消息进行哈希处理的结果,而sig是签名. 通过返回nil错误指示有效签名. opts参数可以为nil,在这种情况下,使用合理的默认值.

type CRTValue

CRTValue包含预先计算的中文余数定理值.

type CRTValue struct {
    Exp   *big.Int // D mod (prime-1).
    Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
    R     *big.Int // product of primes prior to this (inc p and q).
}

type OAEPOptions 1.5

OAEPOptions是用于使用crypto.Decrypter接口将选项传递给OAEP解密的接口.

type OAEPOptions struct {
    // Hash is the hash function that will be used when generating the mask.
    Hash crypto.Hash
    // Label is an arbitrary byte string that must be equal to the value
    // used when encrypting.
    Label []byte
}

type PKCS1v15DecryptOptions 1.5

PKCS1v15DecrypterOpts用于使用crypto.Decrypter接口将选项传递给PKCS#1 v1.5解密.

type PKCS1v15DecryptOptions struct {
    // SessionKeyLen is the length of the session key that is being
    // decrypted. If not zero, then a padding error during decryption will
    // cause a random plaintext of this length to be returned rather than
    // an error. These alternatives happen in constant time.
    SessionKeyLen int
}

type PSSOptions 1.2

PSSOptions包含用于创建和验证PSS签名的选项.

type PSSOptions struct {
    // SaltLength controls the length of the salt used in the PSS
    // signature. It can either be a number of bytes, or one of the special
    // PSSSaltLength constants.
    SaltLength int

    // Hash, if not zero, overrides the hash function passed to SignPSS.
    // This is the only way to specify the hash function when using the
    // crypto.Signer interface.
    Hash crypto.Hash // Go 1.4
}

func (*PSSOptions) HashFunc 1.4

func (pssOpts *PSSOptions) HashFunc() crypto.Hash

HashFunc返回pssOpts.Hash,以便PSSOptions实现crypto.SignerOpts.

type PrecomputedValues

type PrecomputedValues struct {
    Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
    Qinv   *big.Int // Q^-1 mod P

    // CRTValues is used for the 3rd and subsequent primes. Due to a
    // historical accident, the CRT for the first two primes is handled
    // differently in PKCS#1 and interoperability is sufficiently
    // important that we mirror this.
    CRTValues []CRTValue
}

type PrivateKey

私钥代表RSA密钥

type PrivateKey struct {
    PublicKey            // public part.
    D         *big.Int   // private exponent
    Primes    []*big.Int // prime factors of N, has >= 2 elements.

    // Precomputed contains precomputed values that speed up private
    // operations, if available.
    Precomputed PrecomputedValues
}

func GenerateKey

func GenerateKey(random io.Reader, bits int) (*PrivateKey, error)

GenerateKey使用随机源random(例如crypto / rand.Reader)生成给定位大小的RSA密钥对.

func GenerateMultiPrimeKey

func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error)

GenerateMultiPrimeKey生成给定位大小和给定随机源的多素数RSA密钥对,如[1]中所建议. 尽管公钥与2质数的情况兼容(实际上是无法区分的),但私钥却不兼容. 因此,可能无法以某些格式导出多素数私钥或随后将其导入其他代码.

[2]中的表1建议了给定大小的最大素数.

[1]美国专利4405829(1972年到期)[2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf

func (*PrivateKey) Decrypt 1.5

func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)

解密使用priv解密密文. 如果opts为nil或* PKCS1v15DecryptOptions类型,则执行PKCS#1 v1.5解密. 否则,选项必须具有* OAEPOptions类型,并且OAEP解密已完成.

func (*PrivateKey) Precompute

func (priv *PrivateKey) Precompute()

预计算会执行一些计算,以加快将来的私钥操作.

func (*PrivateKey) Public 1.4

func (priv *PrivateKey) Public() crypto.PublicKey

Public返回与priv相对应的公钥.

func (*PrivateKey) Sign 1.4

func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Sign用priv签名消化,从rand读取随机性. 如果opts是* PSSOptions,则将使用PSS算法,否则将使用PKCS#1 v1.5.

此方法实现crypto.Signer,这是支持密钥的接口,私有部分保存在密钥中,例如硬件模块. 常见用法应直接使用此软件包中的Sign *函数.

func (*PrivateKey) Validate

func (priv *PrivateKey) Validate() error

验证对密钥执行基本的完整性检查. 如果密钥有效,则返回nil,否则返回描述问题的错误.

type PublicKey

PublicKey表示RSA密钥的公共部分.

type PublicKey struct {
    N *big.Int // modulus
    E int      // public exponent
}

func (*PublicKey) Size 1.11

func (pub *PublicKey) Size() int

Size返回以字节为单位的模量大小. 此公钥或通过此公钥的原始签名和密文将具有相同的大小.

by  ICOPY.SITE