64 lines
1.3 KiB
Go
64 lines
1.3 KiB
Go
package common
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
)
|
|
|
|
type RsaPacket struct {
|
|
Sid SessionID
|
|
DataLength uint32
|
|
EncryptedKey []byte
|
|
}
|
|
|
|
func NewRsaPacket(pubKey *rsa.PublicKey, key [32]byte, sid SessionID) (*RsaPacket, error) {
|
|
enc, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, key[:], nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pck := RsaPacket{
|
|
Sid: sid,
|
|
DataLength: uint32(len(enc)),
|
|
EncryptedKey: enc,
|
|
}
|
|
|
|
return &pck, nil
|
|
}
|
|
|
|
func (rsaPck *RsaPacket) ToBytes() []byte {
|
|
bytes := make([]byte, rsaPck.DataLength+8+4)
|
|
copy(bytes[0:8], rsaPck.Sid[:])
|
|
binary.LittleEndian.PutUint32(bytes[8:12], rsaPck.DataLength)
|
|
copy(bytes[12:], rsaPck.EncryptedKey[:])
|
|
return bytes
|
|
}
|
|
|
|
func RsaPacketFromBytes(bytes []byte) *RsaPacket {
|
|
sid := SessionID(bytes[0:8])
|
|
dLen := binary.LittleEndian.Uint32(bytes[8:12])
|
|
data := bytes[12 : 12+dLen]
|
|
|
|
return &RsaPacket{
|
|
Sid: sid,
|
|
DataLength: dLen,
|
|
EncryptedKey: data,
|
|
}
|
|
}
|
|
|
|
func (rsaPck *RsaPacket) ExtractKey(priv *rsa.PrivateKey) ([32]byte, error) {
|
|
// key, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, rsaPck.EncryptedKey, nil)
|
|
key, err := priv.Decrypt(
|
|
rand.Reader,
|
|
rsaPck.EncryptedKey,
|
|
&rsa.OAEPOptions{Hash: crypto.SHA256},
|
|
)
|
|
if err != nil {
|
|
return [32]byte{}, err
|
|
}
|
|
return [32]byte(key[0:32]), nil
|
|
}
|