package video_decrypt import ( "errors" "fmt" "hash/crc32" "io" "math/rand" "net" "net/http" "net/http/httputil" "net/url" "sync" ) type transport struct { http.RoundTripper key string } type handle struct { host string port int reverseUrl string reverseHost string } type bodyWrapper struct { body io.ReadCloser key string } func (b bodyWrapper) Read(p []byte) (int, error) { n, err := b.body.Read(p) if err != io.EOF && err != nil { return n, err } buf, decErr := decryptDataV2(p, b.key) if decErr != nil { return 0, decErr } copy(p, buf) return n, err } func (b bodyWrapper) Close() error { b.body.Close() return nil } const EncryptKeyLen = 14 var freePort = 0 var isStart = false var cacheMap = sync.Map{} func GetHostPath() string { return fmt.Sprintf("http://127.0.0.1:%d", freePort) } //启动服务器 func StartServer(reverseUrl, reverseHost string) error { if isStart { return nil } freePortTmp, err := getFreePort(7003, 8000) if err != nil { return err } freePort = freePortTmp h := &handle{host: "127.0.0.1", port: freePort, reverseUrl: reverseUrl, reverseHost: reverseHost} addr := fmt.Sprintf("0.0.0.0:%d", freePort) fmt.Println("start server:" + addr) go func() { _ = http.ListenAndServe(addr, h) }() isStart = true return nil } func getFreePort(min, max int) (int, error) { for i := min; i <= max; i++ { if portIsFree(i) { return i, nil } } return 0, errors.New("没有可用端口") } func portIsFree(checkPort int) bool { addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("localhost:%d", checkPort)) if err != nil { return false } l, err := net.ListenTCP("tcp", addr) if err != nil { return false } defer l.Close() return true } func (t *transport) RoundTrip(req *http.Request) (resp *http.Response, err error) { defer func() { _ = recover() }() resp, err = t.RoundTripper.RoundTrip(req) if err != nil { return nil, err } body := bodyWrapper{ body: resp.Body, key: req.Header.Get("enc_key"), } resp.Body = body return resp, nil } //启动反向代理 func (server *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) { remote, err := url.Parse(server.reverseUrl) if err != nil { panic(err) } key := r.Header.Get("enc_key") r.Host = server.reverseHost proxy := httputil.NewSingleHostReverseProxy(remote) proxy.Transport = &transport{ RoundTripper: http.DefaultTransport, key: key, } proxy.ServeHTTP(w, r) } //加密数据 func EncryptData(data []byte, key string) ([]byte, error) { if len(key) != EncryptKeyLen { return nil, errors.New("key长度要14个字符") } dataLen := len(data) if dataLen == 0 { return data, nil } sortTable := getSortTable(stringHash(key)) result := make([]byte, dataLen) for i := 0; i < dataLen; i++ { item := data[i] result[i] = sortTable[item] } return result, nil } //解密数据 func decryptData(data []byte, key string) ([]byte, error) { if len(key) != EncryptKeyLen { return nil, errors.New("key长度要14个字符") } dataLen := len(data) if dataLen == 0 { return data, nil } sortTable := getSortTable(stringHash(key)) decTable := make([]byte, 0x100) //解密表,就是key和item互換一下 for i := 0; i < 0x100; i++ { decTable[sortTable[i]] = byte(i) } result := make([]byte, dataLen) for i := 0; i < dataLen; i++ { item := data[i] result[i] = decTable[item] } return result, nil } func decryptDataV2(data []byte, key string) ([]byte, error) { if len(key) == 0 { return nil, errors.New("key长度不能为空") } dataLen := len(data) if dataLen == 0 { return data, nil } sortTable := getSortTableDecV2(key) result := make([]byte, dataLen) for i := 0; i < dataLen; i++ { item := int(data[i]) result[i] = byte(sortTable[item]) } return result, nil } func getSortTableDecV2(key string) map[int]int { mapTable := getSortTableV2(key) mapTableDec := map[int]int{} for key, val := range mapTable { mapTableDec[val] = key } return mapTableDec } func getSortTableV2(key string) map[int]int { mapTable := map[int]int{} for i := 0; i <= 0xff; i++ { mapTable[i] = i } bytes := []byte(key) for i := 0; i < 0xff; i++ { val := randNum(bytes, i+10, i+1, 0xff+1) tmpVal := mapTable[val] mapTable[val] = mapTable[i] mapTable[i] = tmpVal } return mapTable } func randNum(bytes []byte, index, start, end int) int { total := 0 for _, item := range bytes { total += int(item) + index } if total < 0 { total = total * -1 } result := start + (total % (end - start)) return result } //加密排序的表 func getSortTable(keyHash int32) []byte { loadedMap, ok := cacheMap.Load(keyHash) if ok { return loadedMap.([]byte) } curRand := rand.New(rand.NewSource(int64(keyHash))) length := 0x100 //生成256长度的原始數組 baseAry := make([]byte, length) for i := 1; i <= 0xff-1; i++ { baseAry[i] = byte(i) } baseAry[0] = 0xff baseAry[0xff] = 0 //隨機數組 randAry := make([]byte, length) //打亂排序 for i := 0; i < length; i++ { index := curRand.Intn(length - i) randAry[i] = baseAry[index] baseAry[index] = baseAry[length-i-1] } cacheMap.Store(keyHash, randAry) return randAry } func stringHash(s string) int32 { v := int32(crc32.ChecksumIEEE([]byte(s))) if v >= 0 { return v } if -v >= 0 { return -v } return 0 }