算法插件

先把算法的现成插件放前面,方面各位参考:https://share.weiyun.com/XXGUgy78

教程中有详细的方法以及相关的软件,请注意下载网盘中的防盗密钥算法

防盗密钥算法下载更多网盘地址:

***此处内容登录后可见***

温馨提示:此处为隐藏内容,需要登录后可见

算法参数

内容UTF-8编码,示例如下:

sign密钥的三个参数:

1:timestamp  是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的“毫秒数”

2:ip  是指观看用户的ip地址

3:key  12345678     PPVOD视频管理系统-系统设置-防盗设置-防盗密钥

 

加密方法:

用key对timestamp和ip进行aes-128-cbc 格式编码,再从二进制编码为 16进制字符串。

固定值测试:

使用’timestamp=402232232323&ip=172.16.7.33′ key:12345678

得出的结果为:

60f118da2eeb040830542e7b2cf9dd38287a5c2c2ff8acc7d16516c1dd71d0c1b95f16c666624942624c01b5ac65d3f7

然后把密钥放m3u8地址后面,如下:

/index.m3u8?sign=60f118da2eeb040830542e7b2cf9dd38287a5c2c2ff8acc7d16516c1dd71d0c1b95f16c666624942624c01b5ac65d3f7

如何检测自己的算法是否正确:

使用系统自带的api接口,http://localhost:2100/api/testsign?key=读写密钥&sign=你的sign结果

注意你sign算法里面的key必须跟后台的“防盗密钥”一致才能得到结果。

 

 

第一行是PPVOD获取到的你的ip

第二行是你的sign结果

第三行是从你sign结果里面得到的ip 看是否跟第一行的ip一致,如果没有ip或者不一致说明你前端代码获取到的ip跟PPVOD获取到的ip不一致

 

php示范代码:

<?php

$time=time().’000′;

$ip=get_real_ip();

$sign=bin2hex(aes128Encrypt(‘跟软件后台的防盗密钥字符相同’,”timestamp=”.$time.”&ip=”.$ip));

function aes128Encrypt($key, $data) {

$padding = 16 – (strlen($data) % 16);

$data=str_pad($data,strlen($data) + 16 – strlen($data) % 16,chr($padding));

$keySize   = 16;

$ivSize    = 16;

$rawKey = $key;

$genKeyData = ”;

do

{

$genKeyData = $genKeyData.md5( $genKeyData.$rawKey,true);

} while(

strlen( $genKeyData ) < 32

);

$generatedKey = substr($genKeyData, 0, $keySize );

$generatedIV  = substr($genKeyData, 16, 16);

return openssl_encrypt($data,’aes-128-cbc’, $generatedKey, OPENSSL_NO_PADDING, $generatedIV);

}

function get_real_ip(){

$ip=false;

if(!empty($_SERVER[“HTTP_CLIENT_IP”])){

$ip = $_SERVER[“HTTP_CLIENT_IP”];

}

if (!empty($_SERVER[‘HTTP_X_FORWARDED_FOR’])) {

$ips = explode (“, “, $_SERVER[‘HTTP_X_FORWARDED_FOR’]);

if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }

for ($i = 0; $i < count($ips); $i++) {

if (!eregi (“^(10|172\.16|192\.168)\.”, $ips[$i])) {

$ip = $ips[$i];

break;

}

}

}

return ($ip ? $ip : $_SERVER[‘REMOTE_ADDR’]);

}

?>

http://域名/日期文件夹/视频文件名/index.m3u8?sign=<?php echo $sign; ?>

 

实例代码:

 

 

 

应用代码:

 

<?php

$time=time().’000′;

$ip=get_real_ip();

$sign=bin2hex(aes128Encrypt($public_r[‘add_playkey’],”timestamp=”.$time.”&ip=”.$ip));

function aes128Encrypt($key, $data) {

$padding = 16 – (strlen($data) % 16);

$data=str_pad($data,strlen($data) + 16 – strlen($data) % 16,chr($padding));

$keySize   = 16;

$ivSize    = 16;

$rawKey = $key;

$genKeyData = ”;

do

{

$genKeyData = $genKeyData.md5( $genKeyData.$rawKey,true);

} while(

strlen( $genKeyData ) < 32

);

$generatedKey = substr($genKeyData, 0, $keySize );

$generatedIV  = substr($genKeyData, 16, 16);

return openssl_encrypt($data,’aes-128-cbc’, $generatedKey, OPENSSL_NO_PADDING, $generatedIV);

}

 

function get_real_ip(){

$ip=false;

if(!empty($_SERVER[“HTTP_CLIENT_IP”])){

$ip = $_SERVER[“HTTP_CLIENT_IP”];

}

if (!empty($_SERVER[‘HTTP_X_FORWARDED_FOR’])) {

$ips = explode (“, “, $_SERVER[‘HTTP_X_FORWARDED_FOR’]);

if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }

for ($i = 0; $i < count($ips); $i++) {

if (!eregi (“^(10|172\.16|192\.168)\.”, $ips[$i])) {

$ip = $ips[$i];

break;

}

}

}

return ($ip ? $ip : $_SERVER[‘REMOTE_ADDR’]);

}

?>

sign=<?php echo $sign; ?>

 

 

 

以下是asp.net算法

 

 

private string GetSign()

{

string data = “timestamp=” + ConvertDateTimeInt(DateTime.Now).ToString() + “&ip=” + System.Web.HttpContext.Current.Request.UserHostAddress;

ViewBag.signq = data;

string key = “12345678”;

var padding = 16 – (data.Length % 16);

data += new string((char)padding, padding);

var keySize = 16;

var ivSize = 16;

var rawKey = Encoding.Default.GetBytes(key);

MD5 md5 = new MD5CryptoServiceProvider();

byte[] genKeyData = md5.ComputeHash(rawKey);

while (genKeyData.Length < (keySize + ivSize))

{

genKeyData = MergerArray(genKeyData, md5.ComputeHash(MergerArray(genKeyData, rawKey)));

}

 

 

var generatedKey = genKeyData.Take(keySize).ToArray();

var generatedIV = genKeyData.Skip(keySize).Take(ivSize).ToArray();

return   ByteToString(AESEncrypt(data, generatedKey, generatedIV));

 

}

 

public byte[] MergerArray(byte[] First, byte[] Second)

{

byte[] result = new byte[First.Length + Second.Length];

First.CopyTo(result, 0);

Second.CopyTo(result, First.Length);

return result;

}

 

public static byte[] AESEncrypt1(String Data, String Key)

{

 

DESCryptoServiceProvider DES = new DESCryptoServiceProvider();

 

DES.Key = Encoding.UTF8.GetBytes(Key);

DES.Mode = CipherMode.CBC;

DES.Padding = PaddingMode.Zeros;

 

ICryptoTransform DESEncrypt = DES.CreateEncryptor();

// System.Text.Encoding

return  Encoding.UTF8.GetBytes(Data);

// return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length));

}

 

/// <summary>

/// AES加密(无向量)

/// </summary>

/// <param name=”plainBytes”>被加密的明文</param>

/// <param name=”key”>密钥</param>

/// <returns>密文</returns>

public static byte[] AESEncrypt(String Data, String Key)

{

MemoryStream mStream = new MemoryStream();

RijndaelManaged aes = new RijndaelManaged();

 

byte[] plainBytes = Encoding.UTF8.GetBytes(Data);

Byte[] bKey = new Byte[32];

Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

 

aes.Mode = CipherMode.ECB;

aes.Padding = PaddingMode.PKCS7;

aes.KeySize = 128;

//aes.Key = _key;

aes.Key = bKey;

//aes.IV = _iV;

CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);

try

{

cryptoStream.Write(plainBytes, 0, plainBytes.Length);

cryptoStream.FlushFinalBlock();

return mStream.ToArray();

//return Convert.ToBase64String(mStream.ToArray());

}

finally

{

cryptoStream.Close();

mStream.Close();

aes.Clear();

}

}

 

/// <summary>

/// 将c# DateTime时间格式转换为Unix时间戳格式

/// </summary>

/// <param name=”time”>时间</param>

/// <returns>long</returns>

public static long ConvertDateTimeInt(System.DateTime time)

{

//double intResult = 0;

System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));

//intResult = (time- startTime).TotalMilliseconds;

long t = (time.Ticks – startTime.Ticks) / 10000;            //除10000调整为13位

return t;

}

 

public  string ByteToString(byte[] InBytes)

{

string StringOut = “”;

foreach (byte InByte in InBytes)

{

StringOut = StringOut + String.Format(“{0:X2} “, InByte).Trim();

}

return StringOut;

}

 

 

public string ByteToString1(byte[] InBytes)

{

string StringOut = “”;

foreach (byte InByte in InBytes)

{

StringOut = StringOut + (char)InByte;

}

return StringOut;

}

/// <summary>

/// 有密码的AES加密

/// </summary>

/// <param name=”text”>加密字符</param>

/// <param name=”password”>加密的密码</param>

/// <param name=”iv”>密钥</param>

/// <returns></returns>

public static byte[] AESEncrypt(string text, byte[] password, byte[] iv)

{

RijndaelManaged rijndaelCipher = new RijndaelManaged();

 

rijndaelCipher.Mode = CipherMode.CBC;

 

rijndaelCipher.Padding = PaddingMode.Zeros;

 

rijndaelCipher.KeySize = 128;

 

rijndaelCipher.BlockSize = 128;

 

byte[] pwdBytes = password;

 

byte[] keyBytes = new byte[16];

 

int len = pwdBytes.Length;

 

if (len > keyBytes.Length) len = keyBytes.Length;

 

System.Array.Copy(pwdBytes, keyBytes, len);

 

rijndaelCipher.Key = keyBytes;

 

 

byte[] ivBytes =iv;

rijndaelCipher.IV = ivBytes;

 

ICryptoTransform transform = rijndaelCipher.CreateEncryptor();

 

byte[] plainText = Encoding.UTF8.GetBytes(text);

 

byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);

 

return cipherBytes;

 

}

 

/// <summary>

/// 随机生成密钥

/// </summary>

/// <returns></returns>

public static string GetIv(int n)

{

char[] arrChar = new char[]{

‘a’,’b’,’d’,’c’,’e’,’f’,’g’,’h’,’i’,’j’,’k’,’l’,’m’,’n’,’p’,’r’,’q’,’s’,’t’,’u’,’v’,’w’,’z’,’y’,’x’,

‘0’,’1′,’2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′,

‘A’,’B’,’C’,’D’,’E’,’F’,’G’,’H’,’I’,’J’,’K’,’L’,’M’,’N’,’Q’,’P’,’R’,’T’,’S’,’V’,’U’,’W’,’X’,’Y’,’Z’

};

 

StringBuilder num = new StringBuilder();

 

Random rnd = new Random(DateTime.Now.Millisecond);

for (int i = 0; i < n; i++)

{

num.Append(arrChar[rnd.Next(0, arrChar.Length)].ToString());

 

}

 

return num.ToString();

}

 

/// <summary>

/// AES解密

/// </summary>

/// <param name=”text”></param>

/// <param name=”password”></param>

/// <param name=”iv”></param>

/// <returns></returns>

public static string AESDecrypt(string text, string password, string iv)

{

RijndaelManaged rijndaelCipher = new RijndaelManaged();

 

rijndaelCipher.Mode = CipherMode.CBC;

 

rijndaelCipher.Padding = PaddingMode.PKCS7;

 

rijndaelCipher.KeySize = 128;

 

rijndaelCipher.BlockSize = 128;

 

byte[] encryptedData = Convert.FromBase64String(text);

 

byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(password);

 

byte[] keyBytes = new byte[16];

 

int len = pwdBytes.Length;

 

if (len > keyBytes.Length) len = keyBytes.Length;

 

System.Array.Copy(pwdBytes, keyBytes, len);

 

rijndaelCipher.Key = keyBytes;

 

byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);

rijndaelCipher.IV = ivBytes;

 

ICryptoTransform transform = rijndaelCipher.CreateDecryptor();

 

byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);

 

return Encoding.UTF8.GetString(plainText);

 

}

PPVOD【CPU授权】:500/1个月,1000/3个月,1500/6个月,2000/12个月 PPVOD【GPU授权】:700/1个月,6000/12个月 BTCDN:700/12个月 直播授权:2000/12个月 GPU授权用户需要WIN系统,必须N卡,算力最好6.0以上 CPU授权用户支持Windows/Linux系统,推荐使用Linux系统 购买地址:https://shop.mingchuang.cc/search/brand/3.html 注册用户购买不需要登记手机号码,游客登入需要登记手机号码。 请注意购买时间和续费时间需要在上班时间内完成,上班时间:上午9点至晚上9点。

在网站右侧就可以联系

https://www.ppvod.cc/soft/#soft

https://www.ppvod.cc/soft/#enclosure

https://www.ppvod.cc/soft/#introduce