WiiUDownloader/keygen.go
2023-09-08 17:30:57 +02:00

81 lines
1.6 KiB
Go

package wiiudownloader
import (
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"crypto/sha1"
"golang.org/x/crypto/pbkdf2"
)
const (
KEYGEN_SECRET = "fd040105060b111c2d49"
)
var (
keygen_pw = []byte{0x6d, 0x79, 0x70, 0x61, 0x73, 0x73}
)
func encryptAES(data, key, iv []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
paddedData := PKCS7Padding(data, aes.BlockSize)
encrypted := make([]byte, len(paddedData))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(encrypted, paddedData)
return encrypted, nil
}
func GenerateKey(tid string) ([]byte, error) {
tmp := []byte(tid)
for tmp[0] == '0' && tmp[1] == '0' {
tmp = tmp[2:]
}
h := []byte(KEYGEN_SECRET + string(tmp))
bhl := len(h) >> 1
bh := make([]byte, bhl)
for i, j := 0, 0; j < bhl; i += 2 {
bh[j] = byte((h[i]%32+9)%25*16 + (h[i+1]%32+9)%25)
j++
}
md5sum := md5.Sum(bh)
key := pbkdf2WithSHA1(keygen_pw, md5sum[:], 20, 16)
iv := make([]byte, 16)
for i, j := 0, 0; j < 8; i += 2 {
iv[j] = byte((tid[i]%32+9)%25*16 + (tid[i+1]%32+9)%25)
j++
}
copy(iv[8:], make([]byte, 8))
encrypted, err := encryptAES(key, commonKey, iv)
if err != nil {
return []byte{}, err
}
return encrypted, nil
}
func pbkdf2WithSHA1(password, salt []byte, iterations, keyLength int) []byte {
return pbkdf2.Key(password, salt, iterations, keyLength, sha1.New)
}
func PKCS7Padding(data []byte, blockSize int) []byte {
padding := blockSize - (len(data) % blockSize)
paddedData := make([]byte, len(data)+padding)
copy(paddedData, data)
for i := len(data); i < len(paddedData); i++ {
paddedData[i] = byte(padding)
}
return paddedData
}