gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/xcrypto/pkcs12/crypto.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package pkcs12 6 7 import ( 8 "bytes" 9 "crypto/cipher" 10 "crypto/des" 11 "crypto/x509/pkix" 12 "encoding/asn1" 13 "errors" 14 15 "gitee.com/ks-custle/core-gm/xcrypto/pkcs12/internal/rc2" 16 ) 17 18 var ( 19 oidPBEWithSHAAnd3KeyTripleDESCBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) 20 oidPBEWithSHAAnd40BitRC2CBC = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 6}) 21 ) 22 23 // pbeCipher is an abstraction of a PKCS#12 cipher. 24 type pbeCipher interface { 25 // create returns a cipher.Block given a key. 26 create(key []byte) (cipher.Block, error) 27 // deriveKey returns a key derived from the given password and salt. 28 deriveKey(salt, password []byte, iterations int) []byte 29 // deriveKey returns an IV derived from the given password and salt. 30 deriveIV(salt, password []byte, iterations int) []byte 31 } 32 33 type shaWithTripleDESCBC struct{} 34 35 func (shaWithTripleDESCBC) create(key []byte) (cipher.Block, error) { 36 return des.NewTripleDESCipher(key) 37 } 38 39 func (shaWithTripleDESCBC) deriveKey(salt, password []byte, iterations int) []byte { 40 return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 24) 41 } 42 43 func (shaWithTripleDESCBC) deriveIV(salt, password []byte, iterations int) []byte { 44 return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) 45 } 46 47 type shaWith40BitRC2CBC struct{} 48 49 func (shaWith40BitRC2CBC) create(key []byte) (cipher.Block, error) { 50 return rc2.New(key, len(key)*8) 51 } 52 53 func (shaWith40BitRC2CBC) deriveKey(salt, password []byte, iterations int) []byte { 54 return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 1, 5) 55 } 56 57 func (shaWith40BitRC2CBC) deriveIV(salt, password []byte, iterations int) []byte { 58 return pbkdf(sha1Sum, 20, 64, salt, password, iterations, 2, 8) 59 } 60 61 type pbeParams struct { 62 Salt []byte 63 Iterations int 64 } 65 66 func pbDecrypterFor(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, int, error) { 67 var cipherType pbeCipher 68 69 switch { 70 case algorithm.Algorithm.Equal(oidPBEWithSHAAnd3KeyTripleDESCBC): 71 cipherType = shaWithTripleDESCBC{} 72 case algorithm.Algorithm.Equal(oidPBEWithSHAAnd40BitRC2CBC): 73 cipherType = shaWith40BitRC2CBC{} 74 default: 75 return nil, 0, NotImplementedError("algorithm " + algorithm.Algorithm.String() + " is not supported") 76 } 77 78 var params pbeParams 79 if err := unmarshal(algorithm.Parameters.FullBytes, ¶ms); err != nil { 80 return nil, 0, err 81 } 82 83 key := cipherType.deriveKey(params.Salt, password, params.Iterations) 84 iv := cipherType.deriveIV(params.Salt, password, params.Iterations) 85 86 block, err := cipherType.create(key) 87 if err != nil { 88 return nil, 0, err 89 } 90 91 return cipher.NewCBCDecrypter(block, iv), block.BlockSize(), nil 92 } 93 94 func pbDecrypt(info decryptable, password []byte) (decrypted []byte, err error) { 95 cbc, blockSize, err := pbDecrypterFor(info.Algorithm(), password) 96 if err != nil { 97 return nil, err 98 } 99 100 encrypted := info.Data() 101 if len(encrypted) == 0 { 102 return nil, errors.New("pkcs12: empty encrypted data") 103 } 104 if len(encrypted)%blockSize != 0 { 105 return nil, errors.New("pkcs12: input is not a multiple of the block size") 106 } 107 decrypted = make([]byte, len(encrypted)) 108 cbc.CryptBlocks(decrypted, encrypted) 109 110 psLen := int(decrypted[len(decrypted)-1]) 111 if psLen == 0 || psLen > blockSize { 112 return nil, ErrDecryption 113 } 114 115 if len(decrypted) < psLen { 116 return nil, ErrDecryption 117 } 118 ps := decrypted[len(decrypted)-psLen:] 119 decrypted = decrypted[:len(decrypted)-psLen] 120 if bytes.Compare(ps, bytes.Repeat([]byte{byte(psLen)}, psLen)) != 0 { 121 return nil, ErrDecryption 122 } 123 124 return 125 } 126 127 // decryptable abstracts an object that contains ciphertext. 128 type decryptable interface { 129 Algorithm() pkix.AlgorithmIdentifier 130 Data() []byte 131 }