网易云音乐ncm编解码原理
背景
办了个网易黑胶会员,想着整个无损音乐库放walkman里听,不再受流量和音质的苦。万万没想到网易自己搞了个ncm的格式,见都没见过,walkman上没法识别,据说会员过期了还不给播了。
我知道了,这是租赁不是购买,看了下网友们对网易云的口诛笔伐,我倒没啥感觉,黑胶会员这个价格,你说买站内所有音乐版权肯定是不够的,租赁也没啥问题。就是音乐搞租赁这个做法以前没见过不太习惯,我就想在我的随身听上播放ncm仅此而已。
网上有挺多奇技淫巧比如从mv转,从h5元素里抓url等等,感觉都差点意思,想着能不能写个ncm转常见无损格式的软件。为此还去学习了一下音频格式以及编解码的一些基础知识。
研究了大半天,遇到了很多无法逾越的问题,后来在github上发现了有人用c++基于openssl库编写了ncm转码 https://github.com/anonymous5l/ncmdump 。之后陆续出现了用python,golang,android,.NET等平台移植的转换库。才疏学浅,那不重复造轮子了,就对着源码做个逆向分析。
思路
有几个问题
- 何为无损?无损就是HiFi的意思吗?
- ncm是怎样的格式?是网易自研的编码还是在无损格式上套一层壳?(且先不质疑网易的技术实力,目前音频编码格式已经很成熟了,自研已无必要,我倾向猜它是为了商业目的在套壳)
- 如果不是套壳,那如何知道一首歌原来的格式,是转成flac,wav还是ape?
- mp3,flac,wav,wmv,ape等等这些格式有啥区别?
嗯 我研究了一下 答案在后面
音频的基础概念
这里有几个音频的基础概念
- 声音: 20Hz~20kHz 可以被人耳识别到的声波
- 采样率:指计算机每秒钟采集多少个声音样本,自然界的声音是模拟信号,这种模拟信号被相关设备通过“采样”、“量化”后,以数字的方式存放在计算机中。根据奈奎斯特采样理论:只要采样频率不低于声音信号最高频率的两倍,采样得到的数字信号就能保真地记录、还原声音。既然人耳能听到音频信号频率大约在20Hz-20KHz之间,根据奈奎斯特采样理论,如果采样频率大于40KHz,那么得到的数字信号就可以高保真的记录模拟信号,就能“HiFi”了。
- 量化精度:样本大小是用每个声音样本的位数bit/s表示,反映度量声波幅度的精度。样本位数的大小影响到声音的质量,位数越多,则精度越高,声音的质量越高,而需要的存储空间也越多。
- 编码:编码是指用二进制数来表示每个采样的量化值。如果量化是均匀的, 又采用自然二进制数表示,这种编码方法就是脉冲编码调制(PCM), 这是一种最简单粗暴却效率最高的编码方法。
所以上面说的奈奎斯特采样理论得出的HiFi,这是“音源”HiFi,这东西是玄学,如果音源HiFi,但是你的设备解码能力不行,或者是耳机表现力度不行,那最终的结果还是达不到HiFi水准,所以现在很多土豪在烧器材设备,一分钱一分货,一块钱两分货,追求的就是那种,与原来的声音高度相似的重放声音的,“高保真”听感。
目前能够达到最高保真水平的就是PCM编码,CD中采用的就是这种编码格式,即无损编码。
有损音乐格式主要有:MP3、WMA、AAC等等,当年周杰伦时代我们手里拿的纽曼mp3随身听,见到最多的格式就是这三种,一首大概3M左右。对文件进行了不可逆向的压缩,从频谱上看上半部分都被切掉了。 用比如spek这类专业的音频分析软件,可以验证出一首无损音乐是真无损还是败絮其中的假无损。
无损音乐格式主要有WAV、AIFF、FLAC、APE、ALAC等等,WAV、AIFF是CD的数字记录,基本上是由CD转成数字形式所得到的文件;而APE、FLAC等是对WAV文件进行无损压缩后得到的,即再加工得到。所以,wav是无损音乐文件,而APE、FLAC等则是无损压缩音乐文件。AIFF是苹果自研,WAV是微软自研。
这么一说,WAV可以直接播放,而常见的APE、FIAC等其他压缩格式则需要经过解压(解码)还原成WAV才能播放。这需要一定的cpu计算成本,会影响续航。walkman随身听官网上对设备的续航介绍,播放不同格式的音乐,续航持久能力也是不一样的。
得出初步结论,如果不是套壳希望能把ncm直接转成wav的格式。如果是套壳,就把它转成原本的格式。
所谓不可逾越的困难
- 拿不到ncm格式的协议。无论是套壳还是自研格式,没有格式的协议,就没法准确的分解二进制文件。
- 拿不到密钥。如果是套壳,肯定是会被加密的,没有密钥就没法decode。
编解码原理
核心代码已标注,A B C D 四块
其中的两次AES加密的密钥,是从哪里搞来的,天上掉下来的,只能这么猜了,不能再往深的去猜了。。。
A 是AES对称加密算法中,的基础加密方式ECB(Electronic Codebook Book)的解码。这种方式会把密文分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。所以从web前端爬url的方案难度是比较大的,得一个个解密再拼接。
B 是标准RC4-KSA算法(Key-scheduling algorithm)。
C 是base64解码+AES对称加密的解码,为什么套base64,base64编码可用于在HTTP环境下传递较长的标识信息。
D 是RC4-PRGA算法(Pseudo-random generation algorithm)还原s-box。
所以通过逆向,还原一下网易云音乐加壳的过程。
- 1.先对该无损音乐进行RC4-KSA算法初始化。
- 2.然后把初始化的产物用AES算法做一层加密。
- 3.再对AES加密后的产物套一层base64编码。
- 4.再对base64编码后的产物做RC4-PRGA加密算法,即伪随机子密码生成算法。
- 5.最后再对这个产物做一层AES加密。
这其中会在一些步骤中加入一些特有的标识比如neteasecloudmusic,以及magic串,这些细节就不写了。
有疑问加站长微信联系(非本文作者)