Пример #1
0
// Like GosaDecrypt() but operates in-place on buf.
// Returns true if decryption successful and false if not.
// If false is returned, the buffer contents may be destroyed, but only
// if further decryption attempts with other keys would be pointless anyway,
// because of some fatal condition (such as the data not being a multiple of
// the cipher's block size).
func GosaDecryptBuffer(buf *bytes.Buffer, key string) bool {
	buf.TrimSpace()

	if buf.Len() < 11 {
		return false
	} // minimum length of unencrypted <xml></xml>

	data := buf.Bytes()
	if string(data[0:5]) == "<xml>" {
		return true
	}

	// Fixes the following:
	// * gosa-si bug in the following line:
	//     if( $client_answer =~ s/session_id=(\d+)$// ) {
	//   This leaves the "." before "session_id" which breaks base64
	// * new gosa-si protocol has ";IP:PORT" appended to message
	//   which also breaks base64
	for semicolon_period := 0; semicolon_period < len(data); semicolon_period++ {
		if data[semicolon_period] == ';' || data[semicolon_period] == '.' {
			buf.Trim(0, semicolon_period)
			data = buf.Bytes()
			break
		}
	}

	aescipher, _ := aes.NewCipher([]byte(util.Md5sum(key)))
	crypter := cipher.NewCBCDecrypter(aescipher, config.InitializationVector)

	cryptotest := make([]byte, (((3*aes.BlockSize)+2)/3)<<2)
	n := copy(cryptotest, data)
	cryptotest = cryptotest[0:n]
	cryptotest = util.Base64DecodeInPlace(cryptotest)
	n = (len(cryptotest) / aes.BlockSize) * aes.BlockSize
	cryptotest = cryptotest[0:n]
	crypter.CryptBlocks(cryptotest, cryptotest)
	if !strings.Contains(string(cryptotest), "<xml>") {
		return false
	}

	data = util.Base64DecodeInPlace(data)
	buf.Trim(0, len(data))
	data = buf.Bytes()

	if buf.Len()%aes.BlockSize != 0 {
		// this condition is fatal => further decryption attempts are pointless
		buf.Reset()
		return false
	}

	crypter = cipher.NewCBCDecrypter(aescipher, config.InitializationVector)
	crypter.CryptBlocks(data, data)

	buf.TrimSpace() // removes 0 padding, too

	return true
}
Пример #2
0
func DecryptFile(filepath string, key []byte) {

	fmt.Println()

	cipherText, err := os.Open(filepath)
	if err != nil {
		fmt.Println("ERROR:", err)
	}
	defer cipherText.Close()

	plainText, err := os.Create(filepath + ".dec")
	if err != nil {
		fmt.Println("ERROR:", err)
	}
	defer plainText.Close()

	iv := make([]byte, 16) //AES const

	_, err = cipherText.Read(iv)
	fmt.Println("iv=", iv[:])
	if err != nil {
		fmt.Println("ERROR:", err)
	}

	encBlock := make([]byte, 16) // AES const
	block, err := aes.NewCipher(key)
	if err != nil {
		fmt.Println("ERROR:", err)
	}

	mode := cipher.NewCBCDecrypter(block, iv)
	// we have decrypter, can loop over file contents now

	// know size so can not get EOF'd
	stats, err := cipherText.Stat()
	if err != nil {
		fmt.Println("ERROR:", err)
	}
	var ReadAmt int64 = 16
	message := make([]byte, 16)

	for ReadAmt != stats.Size() {
		//read in file, decrypt, check for end, if so strip padding
		if _, err := cipherText.Read(encBlock); err != nil {
			fmt.Println("ERROR:", err)
		}

		ReadAmt += 16 // AES const
		mode.CryptBlocks(message, encBlock)

		//check for end, if so strip pad
		fmt.Println("encrypt=", encBlock[:])
		fmt.Println("message=", message[:])
		if ReadAmt == stats.Size() {
			pad := message[15]
			message = message[:16-pad]
		}
		plainText.Write(message)
	}
}
Пример #3
0
func cipherAES(key, iv []byte, isRead bool) interface{} {
	block, _ := aes.NewCipher(key)
	if isRead {
		return cipher.NewCBCDecrypter(block, iv)
	}
	return cipher.NewCBCEncrypter(block, iv)
}
Пример #4
0
// Open decrypts and authenticates the ciphertext.
func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
	if len(ciphertext) < ctx.authtagBytes {
		return nil, errors.New("square/go-jose: invalid ciphertext (too short)")
	}

	offset := len(ciphertext) - ctx.authtagBytes
	expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset])
	match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:])
	if match != 1 {
		return nil, errors.New("square/go-jose: invalid ciphertext (auth tag mismatch)")
	}

	cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce)

	// Make copy of ciphertext buffer, don't want to modify in place
	buffer := append([]byte{}, []byte(ciphertext[:offset])...)

	if len(buffer)%ctx.blockCipher.BlockSize() > 0 {
		return nil, errors.New("square/go-jose: invalid ciphertext (invalid length)")
	}

	cbc.CryptBlocks(buffer, buffer)

	// Remove padding
	plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize())
	if err != nil {
		return nil, err
	}

	ret, out := resize(dst, len(dst)+len(plaintext))
	copy(out, plaintext)

	return ret, nil
}
func (s SecureStorage) decrypt(text1 []byte) (string, error) {
	var data []byte

	// The decrypt may be called with un-encrypted data (the hash key to random,
	//   may be OK in some cases thus thiis has to be verified by the caller)
	defer func() (string, error) {
		if r := recover(); r != nil {
			return "", fmt.Errorf("during decryption: '%v'", text1)
		}
		return string(data), nil
	}()

	text, err := base64.StdEncoding.DecodeString(string(text1))
	if err != nil {
		return "", fmt.Errorf("during decryption: '%v', error: %v", text, err)
	}

	block, err := aes.NewCipher(s.secret)
	if err != nil {
		return "", fmt.Errorf("during decryption: '%v', error: %v", text, err)
	}
	if len(text) < aes.BlockSize {
		return "", fmt.Errorf("Error during decryption: Ciphertext too short")
	}
	iv := text[:aes.BlockSize]
	dtext := text[aes.BlockSize:]
	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(dtext, dtext)
	return string(dtext), nil
}
Пример #6
0
func (c *AESCBCBlockCipher) decrypt(cipherText []byte) ([]byte, error) {
	if c.err != nil {
		return nil, c.err
	}

	bs := c.block.BlockSize()
	if len(cipherText)%bs != 0 {
		return nil, fmt.Errorf("Need a multiple of the blocksize")
	}

	mode := cipher.NewCBCDecrypter(c.block, c.iv)

	// CryptBlocks can work in-place if the two arguments are the same.
	mode.CryptBlocks(cipherText, cipherText)

	// If the original plainText lengths are not a multiple of the block
	// size, padding would have to be added when encrypting, which would be
	// removed at this point. For an example, see
	// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's
	// critical to note that cipherTexts must be authenticated (i.e. by
	// using crypto/hmac) before being decrypted in order to avoid creating
	// a padding oracle.

	return stripPadding(cipherText), nil
}
Пример #7
0
func (s *descbc) Decrypt(salt []byte, algo, usage int, data []byte) ([]byte, error) {
	var h hash.Hash

	switch algo {
	case cryptDesCbcMd5:
		h = md5.New()
	case cryptDesCbcMd4:
		h = md4.New()
	default:
		return nil, ErrProtocol
	}

	if (len(data) & 7) != 0 {
		return nil, ErrProtocol
	}

	iv := [8]byte{}
	b, _ := des.NewCipher(s.key)
	c := cipher.NewCBCDecrypter(b, iv[:])
	c.CryptBlocks(data, data)

	chk := make([]byte, h.Size())
	h.Write(data[:8])
	h.Write(chk) // Just need h.Size() zero bytes instead of the checksum
	h.Write(data[8+len(chk):])
	h.Sum(chk[:0])

	if subtle.ConstantTimeCompare(chk, data[8:8+len(chk)]) != 1 {
		return nil, ErrProtocol
	}

	return data[8+len(chk):], nil
}
Пример #8
0
// Takes json string
func Decrypt(s string, password string) (string, error) {
	var obj Crypto
	if err := json.Unmarshal([]byte(s), &obj); err != nil {
		return "", err
	}

	iv, err := base64.StdEncoding.DecodeString(obj.Iv)
	if err != nil {
		return "", err
	}

	salt, err := base64.StdEncoding.DecodeString(obj.Salt)
	if err != nil {
		return "", err
	}

	ct, err := base64.StdEncoding.DecodeString(obj.Ct)
	if err != nil {
		return "", err
	}

	key := buildDecryptionKey(password, string(salt))

	block, err := aes.NewCipher(key[:32])
	if err != nil {
		panic(err)
	}

	decrypter := cipher.NewCBCDecrypter(block, iv)
	data := make([]byte, len(ct))
	decrypter.CryptBlocks(data, ct)

	return string(data), nil
}
Пример #9
0
// AES256CBCDecrypt decrypts the given ciphertext with AES-256 in CBC mode and
// returns the resulting plaintext. The supplied key must be 32 bytes long and
// the ciphertext must be prepended by the corresponding IV.
func AES256CBCDecrypt(key, ciphertext []byte) (plaintext []byte) {
	if len(key) != 32 {
		panic(log.Critical("cipher: AES-256 key is not 32 bytes long"))
	}
	block, _ := aes.NewCipher(key) // correct key length was enforced above

	// The IV needs to be unique, but not secure. Therefore it's common to
	// include it at the beginning of the ciphertext.
	if len(ciphertext) < aes.BlockSize {
		panic(log.Critical("cipher: ciphertext too short"))
	}
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]
	plaintext = make([]byte, len(ciphertext))

	// CBC mode always works in whole blocks.
	if len(ciphertext)%aes.BlockSize != 0 {
		panic(log.Critical("cipher: ciphertext is not a multiple of the block size"))
	}

	mode := cipher.NewCBCDecrypter(block, iv)

	// CryptBlocks can work in-place if the two arguments are the same.
	mode.CryptBlocks(plaintext, ciphertext)

	return
}
Пример #10
0
// Decrypt decrypts the provided ciphertext, reversing the Encrypt method.
func Decrypt(ciphertext []byte, passphrase string) []byte {
	key := makeKeySlice(passphrase)

	block, err := aes.NewCipher(key)
	if err != nil {
		panic(err)
	}

	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	if len(ciphertext)%aes.BlockSize != 0 {
		panic("ciphertext is not a multiple of the block size")
	}

	mode := cipher.NewCBCDecrypter(block, iv)

	// CryptBlocks can work in-place if the two arguments are the same.
	mode.CryptBlocks(ciphertext, ciphertext)

	padLength := int(uint8(ciphertext[len(ciphertext)-1]))
	unpadded := ciphertext[:len(ciphertext)-padLength]

	return unpadded
}
Пример #11
0
func NewAesCBCCrypter(key []byte, iv []byte) (*AesCBCCrypter, error) {
	l := len(key)
	if l != 32 && l != 24 && l != 16 {
		return nil, errors.New("The key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.")
	}

	block, _ := aes.NewCipher(key)
	blockSize := block.BlockSize()
	if len(iv) != blockSize {
		return nil, errors.New("The length of iv must be the same as the Block's block size " + strconv.Itoa(blockSize))
	}

	this := &AesCBCCrypter{
		blockSize: blockSize,

		encryptBlockMode: cipher.NewCBCEncrypter(block, iv),
		decryptBlockMode: cipher.NewCBCDecrypter(block, iv),

		padding: &PKCS5Padding{
			BlockSize: blockSize,
		},
	}

	return this, nil
}
Пример #12
0
func (c LocalCrypter) Decrypt(b64ciphertext Ciphertext, decryptParams DecryptParams) (string, error) {
	key, err := localKey()
	if err != nil {
		return "", fmt.Errorf("Error retrieving local key: %s", err)
	}
	block, err := aes.NewCipher(key)
	if err != nil {
		return "", fmt.Errorf("Error creating AES cipher: %s", err)
	}

	ciphertext, err := base64.StdEncoding.DecodeString(string(b64ciphertext))
	if err != nil {
		return "", fmt.Errorf("Ciphertext is not valid base64 encoded in secret '%s'", b64ciphertext)
	}
	if len(ciphertext) < aes.BlockSize {
		return "", fmt.Errorf("Ciphertext too short in secret '%s'", ciphertext)
	}
	iv := []byte(ciphertext[:aes.BlockSize])
	ciphertext = ciphertext[aes.BlockSize:]

	if len(ciphertext)%aes.BlockSize != 0 {
		return "", fmt.Errorf("Ciphertext is not a multiple of the block size in secret '%s'", ciphertext)
	}

	mode := cipher.NewCBCDecrypter(block, iv)

	plaintext := make([]byte, len(ciphertext))
	mode.CryptBlocks(plaintext, []byte(ciphertext))

	length := len(plaintext)
	unpadding := int(plaintext[length-1])
	plaintext = plaintext[:(length - unpadding)]
	return string(plaintext), nil
}
Пример #13
0
// Get the plain text out of a frame
func (fr *Frame) PlainText() []DIFs {
	if fr.Key != "" {
		// Check whether the encrypted value is too long, if this is the case it is
		// a plaintext extension and we have to parse this data
		if (len(fr.Value[fr.ValueStart()*2:]) / 2) > fr.ConfigurationLength() {
			return getDIFs(fr.Value[fr.ValueStart()*2+fr.ConfigurationLength()*2:])
		}

		//if(fr.ValueStart()+fr.ConfigurationLength())*2
		key, err := hex.DecodeString(fr.Key)
		if err == nil {
			ciphertext, err := hex.DecodeString(fr.Value[fr.ValueStart()*2:])
			if err == nil {
				block, err := aes.NewCipher(key)
				if err == nil {
					iv, err := hex.DecodeString(fr.IV())
					if err == nil {
						mode := cipher.NewCBCDecrypter(block, iv)
						mode.CryptBlocks(ciphertext, ciphertext)
						plaintext := fmt.Sprintf("%s\n", hex.EncodeToString(ciphertext))
						values := getDIFs(plaintext)
						return values
					}
				}
			}
		}
	}
	return nil
}
Пример #14
0
func cipher3DES(key, iv []byte, isRead bool) interface{} { // 创建3DES算法对称加密
	block, _ := des.NewTripleDESCipher(key)
	if isRead {
		return cipher.NewCBCDecrypter(block, iv)
	}
	return cipher.NewCBCEncrypter(block, iv)
}
Пример #15
0
// Decode decodes the given token and return its data
// and creation time in UTC.
func (tok *T) Decode(token []byte) (data []byte, creation time.Time, err error) {
	raw := make([]byte, base64.RawURLEncoding.DecodedLen(len(token)))
	n, err := base64.RawURLEncoding.Decode(raw, token)
	if err != nil {
		return nil, time.Time{}, err
	}
	raw = raw[:n]
	hash := tok.hmac()
	if len(raw) < aes.BlockSize*2+hash.Size() {
		return nil, time.Time{}, ErrInvalidToken
	}
	soff := len(raw) - hash.Size() // signature offset
	hash.Write(raw[:soff])
	want := hash.Sum(nil)
	have := raw[soff:]
	if !hmac.Equal(want, have) {
		return nil, time.Time{}, ErrInvalidTokenSignature
	}
	iv := raw[:aes.BlockSize]
	body := raw[aes.BlockSize:soff]
	if len(body)%aes.BlockSize != 0 {
		return nil, time.Time{}, ErrInvalidToken
	}
	mode := cipher.NewCBCDecrypter(tok.aes, iv)
	mode.CryptBlocks(body, body)
	ts := time.Unix(int64(binary.BigEndian.Uint32(body)), 0)
	body, err = pkcs7Unpad(body, aes.BlockSize)
	if err != nil {
		return nil, time.Time{}, err
	}
	return body[4:], ts.UTC(), nil
}
Пример #16
0
// Decrypt 方法用于对密文进行解密
//
// 返回解密后的消息,CropId/AppId, 或者错误信息
func (w messageCrypter) decrypt(text string) ([]byte, string, error) {
	var msgDecrypt []byte
	var id string

	deciphered, err := base64.StdEncoding.DecodeString(text)
	if err != nil {
		return nil, "", err
	}

	c, err := aes.NewCipher(w.key)
	if err != nil {
		return nil, "", err
	}

	cbc := cipher.NewCBCDecrypter(c, w.iv)
	cbc.CryptBlocks(deciphered, deciphered)

	decoded := delDecode(deciphered)

	buf := bytes.NewBuffer(decoded[16:20])

	var msgLen int32
	binary.Read(buf, binary.BigEndian, &msgLen)

	msgDecrypt = decoded[20 : 20+msgLen]
	id = string(decoded[20+msgLen:])

	return msgDecrypt, id, nil
}
Пример #17
0
func decryptData(secret_key []byte, encrypted_data []byte) (string, error) {
	block, err := aes.NewCipher(secret_key)
	if err != nil {
		return "", err
	}

	if len(encrypted_data) < aes.BlockSize {
		return "", errors.New("encrypted data is less than BlockSize")
	}

	iv := encrypted_data[:aes.BlockSize]
	data := encrypted_data[aes.BlockSize:]

	if len(data)%aes.BlockSize != 0 {
		return "", errors.New("encrypted data is not a multiple of block size")
	}

	mode := cipher.NewCBCDecrypter(block, iv)

	mode.CryptBlocks(data, data)

	// remove padding
	trimmed_data := strings.TrimRight(string(data), "=")

	return trimmed_data, nil
}
Пример #18
0
func version1Decoder(key []byte, iv, encryptedData string) (interface{}, error) {
	ciphertext := decodeBase64(encryptedData)
	initVector := decodeBase64(iv)
	keySha := sha256.Sum256(key)

	block, err := aes.NewCipher(keySha[:])
	if err != nil {
		return nil, err
	}

	if len(ciphertext)%aes.BlockSize != 0 {
		return nil, errors.New("Ciphertext is wrong length")
	}

	mode := cipher.NewCBCDecrypter(block, initVector)
	mode.CryptBlocks(ciphertext, ciphertext)

	ciphertext = unPKCS7Padding(ciphertext)

	var item version1Item
	_ = json.Unmarshal(ciphertext, &item)

	if item.Content == nil {
		return nil, fmt.Errorf("Decryption failed, check your decryption key.")
	}

	return item.Content, nil
}
Пример #19
0
// Returns a new Reader that reads from r
//
// The header section storing the salt and keys is read from r to verify the file is
// actually a psafe3 file and the password is correct.
//
// All reads from this reader will return unencrypted data.
func NewReader(r io.Reader, password string) (*Reader, error) {
	reader := &Reader{r: r, password: password}

	var header psv3Header
	binary.Read(r, binary.LittleEndian, &header)
	if string(header.Tag[:]) != "PWS3" {
		return nil, ErrBadFileType
	}

	sk := computeStretchKey(header.Salt[:], []byte(password), int(header.Iter))
	hashsk := sha256.Sum256(sk)

	if hashsk != header.HashPPrime {
		return nil, ErrInvalidPassword
	}

	var key, hmacKey [32]byte
	tfish, _ := twofish.NewCipher(sk)
	tfish.Decrypt(key[:16], header.B1[:])
	tfish.Decrypt(key[16:], header.B2[:])
	tfish.Decrypt(hmacKey[:16], header.B3[:])
	tfish.Decrypt(hmacKey[16:], header.B4[:])

	tfish, _ = twofish.NewCipher(key[:])
	reader.tfishDecrypter = cipher.NewCBCDecrypter(tfish, header.IV[:])
	reader.hmacHash = hmac.New(sha256.New, hmacKey[:])

	return reader, nil
}
Пример #20
0
func TestCBC_AES(t *testing.T) {
	for _, tt := range cbcAESTests {
		test := tt.name

		c, err := aes.NewCipher(tt.key)
		if err != nil {
			t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
			continue
		}

		encrypter := cipher.NewCBCEncrypter(c, tt.iv)
		d := make([]byte, len(tt.in))
		encrypter.CryptBlocks(d, tt.in)
		if !bytes.Equal(tt.out, d) {
			t.Errorf("%s: CBCEncrypter\nhave %x\nwant %x", test, d, tt.out)
		}

		decrypter := cipher.NewCBCDecrypter(c, tt.iv)
		p := make([]byte, len(d))
		decrypter.CryptBlocks(p, d)
		if !bytes.Equal(tt.in, p) {
			t.Errorf("%s: CBCDecrypter\nhave %x\nwant %x", test, d, tt.in)
		}
	}
}
Пример #21
0
func decryptMessage(msg []byte, skey []byte) {
	verbose("Decrypting message...", 2)

	/* The first 8 bytes are "Salted__", followed by 8 bytes of salt. */
	salt := msg[8:16]
	msg = msg[16:]

	/* Hack!  Older versions of jass(1) generated a session key with a
	 * trailing '\n', which we have to strip here.  Properly generated
	 * session keys (as this version provides) should _not_ have a '\n' as
	 * the last char.  An old session key would be 45 bytes (32 random
	 * bytes, base64-encoded => 44 bytes + one trailing '\n'), so trim that.
	 *
	 * Backwards compatibility is a bitch. */
	if len(skey) == 45 {
		skey = skey[:len(skey)-1]
	}

	key, iv := bytesToKey(skey, salt)
	block, err := aes.NewCipher(key)
	if err != nil {
		fail(fmt.Sprintf("Unable to set up new cipher: %s\n", err))
	}

	if len(msg)%aes.BlockSize != 0 {
		fail("ciphertext is not a multiple of the block size")
	}

	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(msg, msg)

	msg = unpadBuffer(msg)
	fmt.Printf("%v", string(msg))
}
Пример #22
0
// 使用aes算法,解密指定内容
func DecryptAes(cryptData, key []byte) ([]byte, error) {
	if (len(cryptData) == 0) || (len(key) == 0) {
		return nil, errors.New("decrypt data or secret key is empty")
	}

	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	blockMode := cipher.NewCBCDecrypter(block, key[:aes.BlockSize])

	rawData := make([]byte, len(cryptData))
	// CryptBlocks(dst, src []byte), Dst and src may point to the same memory.
	blockMode.CryptBlocks(rawData, cryptData)

	unpadding := int(rawData[len(rawData)-1])

	if len(rawData) > unpadding {
		rawData = rawData[:(len(rawData) - unpadding)]
	} else {
		return nil, errors.New("decrypt raw data error, key is correct?")
	}

	return rawData, nil
}
Пример #23
0
func decodeCookie(encodedCookie string, key, iv []byte) (map[string]interface{}, error) {
	sessionBytes, err := base64.URLEncoding.DecodeString(encodedCookie)
	if err != nil {
		log.Error("<decodeCookie> ", "base64.Decodestring:", err)
		return nil, err
	}
	aesCipher, err := aes.NewCipher(key)
	if err != nil {
		log.Error("<decodeCookie> ", "aes.NewCipher:", err)
		return nil, err
	}

	decrypter := cipher.NewCBCDecrypter(aesCipher, iv)
	decrypter.CryptBlocks(sessionBytes, sessionBytes)

	buf := bytes.NewBuffer(sessionBytes)
	var gobLen int32
	binary.Read(buf, binary.BigEndian, &gobLen)
	gobBytes := sessionBytes[4 : 4+gobLen]
	session, err := decodeGob(gobBytes)
	if err != nil {
		log.Error("<decodeCookie> ", "decodeGob:", err)
		return nil, err
	}
	return session, nil
}
Пример #24
0
/*
对称解密,
	不会修改输入的数据
*/
func DecryptV2(key []byte, data []byte) (output []byte, err error) {
	if len(data) < 16+64 {
		return nil, errors.New("[kmgCipher.Decrypt] input data too small")
	}
	keyHash := sha512.Sum512(key)
	aseKey := keyHash[:32]
	cbcIv := data[:16]
	block, err := aes.NewCipher(aseKey)
	if err != nil {
		return nil, err
	}
	if len(data)%block.BlockSize() != 0 {
		return nil, errors.New("[kmgCipher.Decrypt] input not full blocks")
	}
	output = make([]byte, len(data)-16)
	blockmode := cipher.NewCBCDecrypter(block, cbcIv)
	blockmode.CryptBlocks(output, data[16:])
	paddingSize := int(output[len(output)-1])
	if paddingSize > block.BlockSize() {
		return nil, errors.New("[kmgCipher.Decrypt] paddingSize out of range")
	}
	beforeCbcSize := len(data) - paddingSize - 64 - 16
	hashData := sha512.Sum512(output[:beforeCbcSize])
	if !bytes.Equal(hashData[:], output[beforeCbcSize:beforeCbcSize+64]) {
		return nil, errors.New("[kmgCipher.Decrypt] hash not match")
	}
	return output[:beforeCbcSize], nil
}
Пример #25
0
/*
rezult 0 - err
       1 - ok
	   2 - капча введена не правильно
	   3 - капча устарела
	   4 - попытка повторного использования капчи
*/
func (t *t_captchaserv) check(w http.ResponseWriter, r *http.Request) {

	defer func() {
		if e := recover(); e != nil {
			fmt.Println(fmt.Errorf("%v", e))
			fmt.Fprint(w, "0")
		}
	}()

	var (
		state_id uint8 = 0
	)

	decryptstr := make([]byte, 16)

	// /captcha/check/+1byte node id
	param := strings.SplitN(r.URL.Path[len(v_captcha.c.Urlcheck)+1:], "/", 2)
	encryptstr, _ := base64.URLEncoding.DecodeString(param[0])

	if t.iv[1].id == encryptstr[0] {
		state_id = 1
	} else if t.iv[0].id != encryptstr[0] {
		fmt.Fprint(w, "3")
		return
	}

	t.rwmu_chang_state.RLock()
	decrypter0 := cipher.NewCBCDecrypter(t.bcipher, t.iv[state_id].val)
	t.rwmu_chang_state.RUnlock()
	decrypter0.CryptBlocks(decryptstr, encryptstr[1:])

	if decryptstr[0] != 33 {
		fmt.Fprint(w, "3")
		return
	}

	id, err := strconv.ParseUint(strings.TrimSpace(string(decryptstr[5:])), 10, 32)
	if err != nil {
		fmt.Fprint(w, "0")
		return
	}

	if string(decryptstr[1:5]) == param[1] {
		if t.db[id] == 100 {
			fmt.Fprint(w, "4")
			return
		}
		fmt.Fprint(w, "1")
		t.db[id] = 100
		return
	}

	if t.db[id] > 1 {
		fmt.Fprint(w, "4")
		t.db[id] = 100
		return
	}
	fmt.Fprint(w, "2")
	t.db[id]++
}
Пример #26
0
func BenchmarkDescryptAesCbc(b *testing.B) {
	key := randomBytes(16)
	iv := randomBytes(16)
	encrypted, err := EncryptIV(original, key, iv)
	if err != nil {
		b.Fatal(err)
	}
	counter := 0
	dataLen := len(encrypted)

	aesCipher, err := aes.NewCipher(key)
	if err != nil {
		b.Fatal(err)
	}
	dec := cipher.NewCBCDecrypter(aesCipher, iv)
	t := time.Now()
	decrypted := make([]byte, len(encrypted))
	b.SetBytes(int64(len(encrypted)))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		dec.CryptBlocks(decrypted, encrypted)
		counter += dataLen
	}
	b.StopTimer()
	ts := time.Since(t)
	b.Logf("decryption speed: %.2f Mbit/s", float64(counter)*8/ts.Seconds()/1024/1024)
}
Пример #27
0
func pbDecrypterFor(algorithm pkix.AlgorithmIdentifier, password []byte) (cipher.BlockMode, int, error) {
	var cipherType pbeCipher

	switch {
	case algorithm.Algorithm.Equal(oidPBEWithSHAAnd3KeyTripleDESCBC):
		cipherType = shaWithTripleDESCBC{}
	case algorithm.Algorithm.Equal(oidPBEWithSHAAnd40BitRC2CBC):
		cipherType = shaWith40BitRC2CBC{}
	default:
		return nil, 0, NotImplementedError("algorithm " + algorithm.Algorithm.String() + " is not supported")
	}

	var params pbeParams
	if err := unmarshal(algorithm.Parameters.FullBytes, &params); err != nil {
		return nil, 0, err
	}

	key := cipherType.deriveKey(params.Salt, password, params.Iterations)
	iv := cipherType.deriveIV(params.Salt, password, params.Iterations)

	block, err := cipherType.create(key)
	if err != nil {
		return nil, 0, err
	}

	return cipher.NewCBCDecrypter(block, iv), block.BlockSize(), nil
}
Пример #28
0
// DecryptPEMBlock takes a password encrypted PEM block and the password used to
// encrypt it and returns a slice of decrypted DER encoded bytes. It inspects
// the DEK-Info header to determine the algorithm used for decryption. If no
// DEK-Info header is present, an error is returned. If an incorrect password
// is detected an IncorrectPasswordError is returned. Because of deficiencies
// in the encrypted-PEM format, it's not always possible to detect an incorrect
// password. In these cases no error will be returned but the decrypted DER
// bytes will be random noise.
func DecryptPEMBlock(b *pem.Block, password []byte) ([]byte, error) {
	dek, ok := b.Headers["DEK-Info"]
	if !ok {
		return nil, errors.New("x509: no DEK-Info header in block")
	}

	idx := strings.Index(dek, ",")
	if idx == -1 {
		return nil, errors.New("x509: malformed DEK-Info header")
	}

	mode, hexIV := dek[:idx], dek[idx+1:]
	ciph := cipherByName(mode)
	if ciph == nil {
		return nil, errors.New("x509: unknown encryption mode")
	}
	iv, err := hex.DecodeString(hexIV)
	if err != nil {
		return nil, err
	}
	if len(iv) != ciph.blockSize {
		return nil, errors.New("x509: incorrect IV size")
	}

	// Based on the OpenSSL implementation. The salt is the first 8 bytes
	// of the initialization vector.
	key := ciph.deriveKey(password, iv[:8])
	block, err := ciph.cipherFunc(key)
	if err != nil {
		return nil, err
	}

	data := make([]byte, len(b.Bytes))
	dec := cipher.NewCBCDecrypter(block, iv)
	dec.CryptBlocks(data, b.Bytes)

	// Blocks are padded using a scheme where the last n bytes of padding are all
	// equal to n. It can pad from 1 to blocksize bytes inclusive. See RFC 1423.
	// For example:
	//	[x y z 2 2]
	//	[x y 7 7 7 7 7 7 7]
	// If we detect a bad padding, we assume it is an invalid password.
	dlen := len(data)
	if dlen == 0 || dlen%ciph.blockSize != 0 {
		return nil, errors.New("x509: invalid padding")
	}
	last := int(data[dlen-1])
	if dlen < last {
		return nil, IncorrectPasswordError
	}
	if last == 0 || last > ciph.blockSize {
		return nil, IncorrectPasswordError
	}
	for _, val := range data[dlen-last:] {
		if int(val) != last {
			return nil, IncorrectPasswordError
		}
	}
	return data[:dlen-last], nil
}
Пример #29
0
func decryptDES(src, key, privParam []byte) (dst []byte, err error) {

	if len(src)%des.BlockSize != 0 {
		err = ArgumentError{
			Value:   len(src),
			Message: "Invalid DES cipher length",
		}
		return
	}
	if len(privParam) != 8 {
		err = ArgumentError{
			Value:   len(privParam),
			Message: "Invalid DES PrivParameter length",
		}
		return
	}

	block, err := des.NewCipher(key[:8])
	if err != nil {
		return
	}

	iv := xor(key[8:16], privParam)
	dst = make([]byte, len(src))

	mode := cipher.NewCBCDecrypter(block, iv)
	mode.CryptBlocks(dst, src)
	return
}
Пример #30
0
// ciphertext = AES_Encrypt[random(16B) + msg_len(4B) + rawXMLMsg + appId]
func AESDecryptMsg(ciphertext []byte, appId string, aesKey [32]byte) (random, rawXMLMsg []byte, err error) {
	const (
		BLOCK_SIZE = 32             // PKCS#7
		BLOCK_MASK = BLOCK_SIZE - 1 // BLOCK_SIZE 为 2^n 时, 可以用 mask 获取针对 BLOCK_SIZE 的余数
	)

	if len(ciphertext) < BLOCK_SIZE {
		err = fmt.Errorf("the length of ciphertext too short: %d", len(ciphertext))
		return
	}
	if len(ciphertext)&BLOCK_MASK != 0 {
		err = fmt.Errorf("ciphertext is not a multiple of the block size, the length is %d", len(ciphertext))
		return
	}

	plaintext := make([]byte, len(ciphertext)) // len(plaintext) >= BLOCK_SIZE

	// 解密
	block, err := aes.NewCipher(aesKey[:])
	if err != nil {
		panic(err)
	}
	mode := cipher.NewCBCDecrypter(block, aesKey[:16])
	mode.CryptBlocks(plaintext, ciphertext)

	// PKCS#7 去除补位
	amountToPad := int(plaintext[len(plaintext)-1])
	if amountToPad < 1 || amountToPad > BLOCK_SIZE {
		err = fmt.Errorf("the amount to pad is invalid: %d", amountToPad)
		return
	}
	plaintext = plaintext[:len(plaintext)-amountToPad]

	// 反拼接
	// len(plaintext) == 16+4+len(rawXMLMsg)+len(appId)
	if len(plaintext) <= 20 {
		err = fmt.Errorf("plaintext too short, the length is %d", len(plaintext))
		return
	}
	rawXMLMsgLen := int(decodeNetworkByteOrder(plaintext[16:20]))
	if rawXMLMsgLen < 0 {
		err = fmt.Errorf("invalid msg length: %d", rawXMLMsgLen)
		return
	}
	appIdOffset := 20 + rawXMLMsgLen
	if len(plaintext) <= appIdOffset {
		err = fmt.Errorf("msg length too large: %d", rawXMLMsgLen)
		return
	}

	appIdHave := string(plaintext[appIdOffset:])
	if appIdHave != appId {
		err = fmt.Errorf("appId mismatch, have: %s, want: %s", appIdHave, appId)
		return
	}

	random = plaintext[:16:20]
	rawXMLMsg = plaintext[20:appIdOffset]
	return
}