shadowsocks/shadowsocks-go

The initial vector is transmitted directly in plaintext

HUANGChaoLi opened this issue · 4 comments

func (c *Conn) Write(b []byte) (n int, err error) {
	var iv []byte
	if c.enc == nil {
		iv, err = c.initEncrypt()
		if err != nil {
			return
		}
	}

	cipherData := c.writeBuf
	dataSize := len(b) + len(iv)
	if dataSize > len(cipherData) {
		cipherData = make([]byte, dataSize)
	} else {
		cipherData = cipherData[:dataSize]
	}

	if iv != nil {
		// Put initialization vector in buffer, do a single write to send both
		// iv and data.
		copy(cipherData, iv)
	}

	c.encrypt(cipherData[len(iv):], b)
	n, err = c.Conn.Write(cipherData)
	return
}

The format is fixed like: | iv | ciphertext |, so the initial vector will be known, and it does not play its role.
Maybe it's safer to use the Diffie-Hellman key exchange algorithm in the shake phase.

If the entire connection is monitored, then all information will be cracked.
Because I can get the key in the stream, this maybe vulnerability.

Thanks for your listening.

Oh, I made a mistake, I mean the initial vector will be known, this maybe vulnerability.
So the mode is equivalent to ECB mode and the initial vector does not play its role.