·您当前的位置:首页 > 技术教程 > AS2与AS3技术 >

[AS3]as3加密算法与as3解密算法实例完整代码

时间:2013-08-27 14:07cuplayer.com
[AS3]as3加密算法与as3解密算法实例完整代码,as3crypto类加密解密Des

[AS3]as3加密算法与as3解密算法实例完整代码

DesCrypt.as代码

  1. package 
  2.     import com.hurlant.util.Base64; 
  3.     import com.hurlant.util.Hex; 
  4.      
  5.     import flash.utils.ByteArray; 
  6.      
  7. public class DesCrypt { 
  8.     private static const bytebit:Array = [ 128, 64, 32, 16, 8, 4, 2, 1 ]; 
  9.     private static const bigbyte:Array = [ 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000, 
  10.                 0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 ]; 
  11.         /* 
  12.          * Use the key schedule specified in the Standard (ANSI X3.92-1981). 
  13.          */ 
  14.     private static const pc1:Array = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 
  15.             59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12,4, 27, 19, 11, 3 ]; 
  16.     private static const totrot:Array = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ]; 
  17.     private static const pc2:Array = [ 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 
  18.             51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ]; 
  19.  
  20.  public function DesCrypt() { 
  21.   //构造 
  22.  } 
  23.  public function  des(key:String, message:String, encrypt:Boolean, mode:uint, iv:String):ByteArray{ 
  24.   //declaring this locally speeds things up a bit 
  25.   var spfunction1:Array = new Array(0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400, 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000, 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4, 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404, 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400, 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004); 
  26.   var spfunction2:Array = new Array(-0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0, -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020, -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000, -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000, -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0, 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0, 0x108000); 
  27.   var spfunction3:Array = new Array(0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008, 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000, 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000, 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0, 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208, 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200); 
  28.   var spfunction4:Array = new Array(0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000, 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080, 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0, 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001, 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080); 
  29.   var spfunction5:Array = new Array(0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000, 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000, 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100, 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100, 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100, 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0, 0x40080000, 0x2080100, 0x40000100); 
  30.   var spfunction6:Array = new Array(0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000, 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010, 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000, 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000, 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000, 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010); 
  31.   var spfunction7:Array = new Array(0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802, 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002, 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000, 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000, 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0, 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002); 
  32.   var spfunction8:Array = new Array(0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000, 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000, 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040, 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000); 
  33.   //create the 16 or 48 subkeys we will need 
  34.   var keys:Array = generateWorkingKey(key);//密钥已经完成 
  35.   var m:uint = 0i:int = 0j:uint = 0, temp,  right1:int0right2:int0, left, right, looping; 
  36.   var cbcleft, cbcleft2, cbcright, cbcright2; 
  37.   var endloop, loopinc; 
  38. //pad the message out with null bytes 填充 
  39. //  var messages:ByteArray = Hex.toArray(Hex.fromString(message)); //这玩艺儿还不能随便先换成String去调用函数 
  40. //  message = urlencodeGBK(message); 
  41.     var messages:ByteArray =new ByteArray; //这玩艺儿还不能随便先换成String去调用函数 
  42. //   messages.writeUTFBytes(message); //这玩艺儿还不能随便先换成String去调用函数 
  43. //   messages = Hex.toArray(Hex.fromString(message)); //这玩艺儿还不能随便先换成String去调用函数 
  44.     if(encrypt){ 
  45.         messages.writeMultiByte(message,"gbk"); 
  46.         pad(messages); 
  47.     }else{ 
  48.         messages.writeBytes(Base64.decodeToByteArray(message)); 
  49.     } 
  50. //  message = Hex.toString(Hex.fromArray(messages)); 
  51.     var len:uint = messages.length;  
  52.     for(var kk:uint = 0; kk < messages.length; kk++){ 
  53.     } 
  54. //  var len:uint = message.length; //这种方法不可取,计算中文长度有问题 
  55. //   messages.length = 0
  56. //  trace("len2:" + messages.length); 
  57.   var chunk:uint = 0
  58.   //set up the loops for single and triple des 
  59.   var iterations:uint = keys.length == 32 ? 3 : 9; 
  60.   //single or triple des 
  61.   if (iterations == 3) { 
  62.    looping = encrypt ? new Array(0, 32, 2) : new Array(30, -2, -2); 
  63.   } else { 
  64.    looping = encrypt ? new Array(0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array(94, 62, -2, 32, 64, 2, 30, -2, -2); 
  65.   } 
  66.  
  67. //store the result here 
  68. //  var result:String = ""
  69. //  var tempresult:String = ""
  70.   var result:ByteArray = new ByteArray; 
  71.   var tempresult:ByteArray = new ByteArray; 
  72.   var outOff:uint = 0
  73.   if (mode == 1) { 
  74.    //CBC mode 
  75.    cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); 
  76.    cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++); 
  77.    m = 0
  78.   } 
  79.   //loop through each 64 bit chunk of the message       
  80.   while (m<len) { 
  81.     //求左右两部分 
  82. //  var messages:ByteArray = Hex.toArray(Hex.fromString(message)); 
  83. //  trace("message.charCodeAt(2):" + message.charCodeAt(2)); 
  84.  
  85. //  left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); 
  86. //  right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++); 
  87.     //字节操作效率高,而且还能有效解决中文问题,不要使用(message.charCodeAt(m++) << 24)方式 
  88.     left = (messages[m++] << 24) | (messages[m++] << 16) | (messages[m++] << 8) | messages[m++]; 
  89.     right = (messages[m++] << 24) | (messages[m++] << 16) | (messages[m++] << 8) | messages[m++]; 
  90.      
  91.      
  92.    //for Cipher Block Chaining mode, xor the message with the previous result 
  93.    if (mode == 1) { 
  94.     if (encrypt) { 
  95.      left ^= cbcleft; 
  96.      right ^= cbcright; 
  97.     } else { 
  98.      cbcleftcbcleft2 = cbcleft; 
  99.      cbcrightcbcright2 = cbcright; 
  100.      cbcleft = left; 
  101.      cbcright = right; 
  102.     } 
  103.    } 
  104.    //first each 64 but chunk of the message must be permuted according to IP       
  105.    temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; 
  106.    right ^= temp; 
  107.    left ^= (temp << 4); 
  108.    temp = ((left >>> 16) ^ right) & 0x0000ffff; 
  109.    right ^= temp; 
  110.    left ^= (temp << 16); 
  111.    temp = ((right >>> 2) ^ left) & 0x33333333; 
  112.    left ^= temp; 
  113.    right ^= (temp << 2); 
  114.    temp = ((right >>> 8) ^ left) & 0x00ff00ff; 
  115.    left ^= temp; 
  116.    right ^= (temp << 8); 
  117.    temp = ((left >>> 1) ^ right) & 0x55555555; 
  118.    right ^= temp; 
  119.    left ^= (temp << 1); 
  120.    left = ((left << 1) | (left >>> 31)); 
  121.    right = ((right << 1) | (right >>> 31)); 
  122.    //do this either 1 or 3 times for each chunk of the message 
  123.    for (j=0; j<iterations; j += 3) { 
  124.     endloop = looping[j+1]; 
  125.     loopinc = looping[j+2]; 
  126.     //now go through and perform the encryption or decryption   
  127.     for (i=looping[j]; i != endloop; i += loopinc) { 
  128.      //for efficiency 
  129.      rightright1 = right ^ keys[i]; 
  130.      right2 = ((right >>> 4) | (right << 28)) ^ keys[i+1]; 
  131.      //the result is attained by passing these bytes through the S selection functions 
  132.      temp = left
  133.      left = right
  134.      right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]); 
  135.     } 
  136.     temp = left
  137.     left = right
  138.     right = temp
  139.     //unreverse left and right 
  140.    } 
  141.    //for either 1 or 3 iterations 
  142.    //move then each one bit to the right 
  143.    left = ((left >>> 1) | (left << 31)); 
  144.    right = ((right >>> 1) | (right << 31)); 
  145.    //now perform IP-1, which is IP in the opposite direction 
  146.    temp = ((left >>> 1) ^ right) & 0x55555555; 
  147.    right ^= temp; 
  148.    left ^= (temp << 1); 
  149.    temp = ((right >>> 8) ^ left) & 0x00ff00ff; 
  150.    left ^= temp; 
  151.    right ^= (temp << 8); 
  152.    temp = ((right >>> 2) ^ left) & 0x33333333; 
  153.    left ^= temp; 
  154.    right ^= (temp << 2); 
  155.    temp = ((left >>> 16) ^ right) & 0x0000ffff; 
  156.    right ^= temp; 
  157.    left ^= (temp << 16); 
  158.    temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; 
  159.    right ^= temp; 
  160.    left ^= (temp << 4); 
  161.    //for Cipher Block Chaining mode, xor the message with the previous result 
  162.    if (mode == 1) { 
  163.     if (encrypt) { 
  164.      cbcleft = left; 
  165.      cbcright = right; 
  166.     } else { 
  167.      left ^= cbcleft2; 
  168.      right ^= cbcright2; 
  169.     } 
  170.    } 
  171.                  
  172.     tempresult[outOff + 0] = (left >>> 24); 
  173.     tempresult[outOff + 1] = ((left >>> 16) & 0xff); 
  174.     tempresult[outOff + 2] = ((left >>> 8) & 0xff); 
  175.     tempresult[outOff + 3] = (left & 0xff); 
  176.     tempresult[outOff + 4] = (right >>> 24); 
  177.     tempresult[outOff + 5] = ((right >>> 16) & 0xff); 
  178.     tempresult[outOff + 6] = ((right >>> 8) & 0xff); 
  179.     tempresult[outOff + 7] = (right & 0xff); 
  180.      
  181.     outOff += 8;     
  182.                  
  183.    if (outOff == 512) {  
  184.         result.writeBytes(tempresult,result.length); 
  185.         tempresult.length = 0
  186.         outOff = 0
  187.    } 
  188.   } 
  189.     result.writeBytes(tempresult,result.length);  
  190.     
  191.   if(encrypt) { //加密 
  192.      return result; 
  193.   }else{//解密 
  194.    
  195.         result.writeBytes(tempresult,result.length) 
  196.         var temary:ByteArray = new ByteArray; 
  197.         temary.writeBytes(result); 
  198.          
  199.         var templen:uint = temary.length - 1; 
  200.         result.length = 0
  201.         result.writeBytes(temary,0,(templen - temary[templen] + 1)); 
  202.      
  203.      return result; 
  204.   } 
  205.    
  206.  } 
  207.         public function generateWorkingKey(keyss:String):Array 
  208.         { 
  209.             var off:uint = 0
  210.             var key:ByteArray = Hex.toArray(Hex.fromString(keyss)); 
  211.             var encrypting:Boolean = true
  212.             //int[] newnewKey = new int[32]; 
  213.             var newKey:Array = []; 
  214.             //boolean[] pc1m = new boolean[56], pcr = new boolean[56]; 
  215.             var pc1m:ByteArray = new ByteArray; 
  216.             var pcr:ByteArray = new ByteArray; 
  217.              
  218.             var l:uint; 
  219.      
  220.             for (var j:uint = 0; j < 56; j++) 
  221.             { 
  222.                 l = pc1[j]; 
  223.      
  224.                 pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0); 
  225.             } 
  226.      
  227.             for (var i:uint = 0; i < 16; i++) 
  228.             { 
  229.                 var m:uint; 
  230.                 var n:uint; 
  231.      
  232.                 if (encrypting) 
  233.                 { 
  234.                     m = i << 1
  235.                 } 
  236.                 else 
  237.                 { 
  238.                     m = (15 - i) << 1
  239.                 } 
  240.      
  241.                 n = m + 1; 
  242.                 newKey[m] = newKey[n] = 0; 
  243.      
  244.                 for (j = 0; j < 28; j++) 
  245.                 { 
  246.                     l = j + totrot[i]; 
  247.                     if (l < 28
  248.                     { 
  249.                         pcr[j] = pc1m[l]; 
  250.                     } 
  251.                     else 
  252.                     { 
  253.                         pcr[j] = pc1m[l - 28]; 
  254.                     } 
  255.                 } 
  256.      
  257.                 for (j = 28; j < 56; j++) 
  258.                 { 
  259.                     l = j + totrot[i]; 
  260.                     if (l < 56
  261.                     { 
  262.                         pcr[j] = pc1m[l]; 
  263.                     } 
  264.                     else 
  265.                     { 
  266.                         pcr[j] = pc1m[l - 28]; 
  267.                     } 
  268.                 } 
  269.      
  270.                 for (j = 0; j < 24; j++) 
  271.                 { 
  272.                     if (pcr[pc2[j]]) 
  273.                     { 
  274.                         newKey[m] |= bigbyte[j]; 
  275.                     } 
  276.      
  277.                     if (pcr[pc2[j + 24]]) 
  278.                     { 
  279.                         newKey[n] |= bigbyte[j]; 
  280.                     } 
  281.                 } 
  282.             } 
  283.      
  284.             // 
  285.             // store the processed key 
  286.             // 
  287.             for (i = 0; i != 32; i += 2) 
  288.             { 
  289.                 var i1:uint; 
  290.                 var i2:uint; 
  291.      
  292.                 i1 = newKey[i]; 
  293.                 i2 = newKey[i + 1]; 
  294.      
  295.                 newKey[i+1] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10) 
  296.                         | ((i2 & 0x00000fc0) >>> 6); 
  297.      
  298.                 newKey[i] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4) 
  299.                         | (i2 & 0x0000003f); 
  300.                          
  301.                         //这里把newKey[i] 和 newKey[i+1]位置对调一下。 
  302.             } 
  303.             return newKey; 
  304.         } 
  305.          
  306.  
  307.         //填充 
  308.         public function pad(a:ByteArray):void { 
  309.             var c:uint = 8-a.length%8; 
  310.             for (var i:uint=0;i<c;i++){ 
  311.                 a[a.length] = c; 
  312.             } 
  313.         } 
  314.          
  315.         public function unpad(a:ByteArray):void { 
  316.             var c:uint = a.length%8; 
  317.             if (c!=0) throw new Error("PKCS#5::unpad: ByteArray.length isn't a multiple of the blockSize"); 
  318.             c = a[a.length-1]; 
  319.             for (var i:uint=c;i>0;i--) { 
  320.                 var v:uint = a[a.length-1]; 
  321.                 a.length--; 
  322.                 if (c!=v) throw new Error("PKCS#5:unpad: Invalid padding value. expected ["+c+"], found ["+v+"]"); 
  323.             } 
  324.         } 
  325.     } 

调用:
internal var dc:DesCrypt = new DesCrypt;
加密:paras.seqno = Base64.encodeByteArray(dc.des(key,seqNo,true,1,key));
解密:
var resultStrs:ByteArray = dc.des(key,ary[1].密文,false,1,key);
resultStrs.position = 0;
var resultStr:String = resultStrs.readMultiByte(resultStrs.length,"gbk");

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器