Closed
Description
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (go version
)?
go version go1.8.1 openbsd/amd64
What operating system and processor architecture are you using (go env
)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="openbsd"
GOOS="openbsd"
GOPATH="/home/stuart/go"
GORACE=""
GOROOT="/home/stuart/.go/1.8.1"
GOTOOLDIR="/home/stuart/.go/1.8.1/pkg/tool/openbsd_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -fmessage-length=0"
CXX="g++"
CGO_ENABLED="0"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
What did you do?
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.
package main
import (
"log"
"golang.org/x/crypto/bcrypt"
)
const HASH = "$2a$10$LK9XRuhNxHHCvjX3tdkRKei1QiCDUKrJRhZv7WWZPuQGRUM92rOUa"
func main() {
a := []byte("passw0rd123456")
password := a[:len(a)-6]
token := a[len(a)-6:]
log.Printf("Before: A:%q T:%q P:%q", a, token, password)
if err := bcrypt.CompareHashAndPassword([]byte(HASH), password); nil != err {
log.Fatalf("Hash mismatch")
}
log.Printf("After: A:%q T:%q P:%q", a, token, password)
}
Output:
2017/05/19 11:58:43 Before: A:"passw0rd123456" T:"123456" P:"passw0rd"
2017/05/19 11:58:43 After: A:"passw0rd\x0023456" T:"\x0023456" P:"passw0rd"
What did you expect to see?
I expected the value of token
to be unchanged after the call to bcrypt.CompareAndHashPassword
.
What did you see instead?
The first byte of token
was changed. This seems to happen in the call to bcrypt.expensiveBlowfishSetup
when it appends a null byte to password
to be compatible with C implementations.
https://github.com/golang/crypto/blob/master/bcrypt/bcrypt.go#L216
Unfortunately this changes the slice's underlying array, which can have knock-on effects if other slices refer to the same array (as in my 2FA-derived example).