Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

更新至 2.1.0rc1 #4

Merged
merged 58 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
4409426
typeutils.py 修改:
nukemiko Nov 24, 2022
fff45b1
common.py:为 StreamCipherSkel 添加了方法 preoperations_plaindata() 和 preope…
nukemiko Nov 24, 2022
5c62445
精简了 StreamCipherProto,仅保留方法 encrypt() 和 decrypt()
nukemiko Nov 24, 2022
e5e241b
typedefs.py:新增 KeyStreamBasedStreamCipherProto,添加了方法 keystream() 和 pr…
nukemiko Nov 24, 2022
3433797
typedefs.KeyStreamBasedStreamCipherProto、common.KeyStreamBasedStreamC…
nukemiko Nov 24, 2022
9582d1f
重构了 `EncryptedBytesIOSkel` 和 `KeyStreamBasedStreamCipherSkel`,从 `KeyS…
nukemiko Dec 15, 2022
2f51654
`bytestrxor()` 引发的异常会包含更详细的信息
nukemiko Dec 15, 2022
5a59613
common.py -> prototypes.py
nukemiko Dec 15, 2022
f41c63c
补充了 `__all__`,修复了一个错误的参数名称
nukemiko Dec 15, 2022
f487c4e
删除了上一次提交遗留的注释
nukemiko Dec 15, 2022
5688682
优化了 `EncryptedBytesIOSkel` 的 repr 显示
nukemiko Dec 16, 2022
f53bf77
尝试重写 NCM 的逻辑,使用 EncryptedBytesIOSkel
nukemiko Dec 16, 2022
cafc0d7
为所有的 Cipher 协议类添加了 getkey() 方法;再次优化了 EncryptedBytesIOSkel 的 repr 显示,以…
nukemiko Dec 18, 2022
31cd3f3
删除了 ARC4 的 master_key 属性,使用 `getkey()` 方法代替
nukemiko Dec 18, 2022
faa8c6c
使用 EncryptedBytesIOSkel 重写了 NCM,实现了探测步骤的分离
nukemiko Dec 18, 2022
1083a4f
完善了 EncryptedBytesIOSkel 的文档
nukemiko Dec 18, 2022
1c83b0f
对 prototypes.py 进行了大量修改:
nukemiko Dec 19, 2022
5a85cd3
为 stdciphers.py 中所有的 Cipher 都应用了 1c83b0f2057b9f6f0f0e5a853360aacb9522…
nukemiko Dec 19, 2022
9e5ccac
为 `StreamCipherBasedCryptedIOProto` 添加只读属性 `master_key`
nukemiko Dec 19, 2022
dad78f9
为 qmckeyciphers.py 中所有的 Cipher 都应用了 1c83b0f2057b9f6f0f0e5a853360aacb9…
nukemiko Dec 19, 2022
c29ef40
补充了 `__all__` 遗漏的 `probe()`
nukemiko Dec 19, 2022
49f45c6
为 qmcdataciphers.py 中所有的 Cipher 都应用了 1c83b0f2057b9f6f0f0e5a853360aacb…
nukemiko Dec 19, 2022
182a170
统一修改了对“simple key”的称谓
nukemiko Dec 20, 2022
52392fb
删除了所有 Cipher 类的 `getkey()` 方法的参数限制
nukemiko Dec 20, 2022
285bc9c
现在 `NCM.open()` 和 `NCM.from_file()` 可接受可选参数 `master_key` 作为主密钥
nukemiko Dec 20, 2022
5728b78
修复了 DeprecationWarning 不生效的问题;修复了 `NCM.save()` 的 filething 参数在设置为 Non…
nukemiko Dec 20, 2022
15c209f
彻底重写了 QMC 相关逻辑,分离了 QMCv2 的探测逻辑
nukemiko Dec 20, 2022
bed3dcc
再次修复了 `NCM.save()` 的文档
nukemiko Dec 20, 2022
e5c422c
改变了 Key256MappingData 所在的目录结构
nukemiko Dec 20, 2022
e81d470
删除了一处不必要的除余操作
nukemiko Dec 22, 2022
5a147dd
将 setuptools 移出软件包依赖列表、设为安装依赖
nukemiko Dec 22, 2022
76bfb0f
修复了打包后的 wheel 包缺少 VERSION 文件的问题
nukemiko Dec 22, 2022
0ff19f8
修改版本号和 README.md
nukemiko Dec 22, 2022
4d96d65
为 `NCM` 和 `CloudMusicIdentifier` 进行了改造,使其与 2.0.x 兼容;补充了弃用警告
nukemiko Dec 24, 2022
94a347b
`CloudMusicIdentifier`:方法 `to_mutagen_tag()` 现在支持在标签中嵌入 163key;修复了方法 …
nukemiko Dec 24, 2022
128a5e5
现在可以直接给 `NCM.ncm_tag` 赋值,不过必须是一个 `CloudMusicIdentifier` 对象
nukemiko Dec 24, 2022
620c9b0
改造了 `QMCv1` 使它和 2.0.x 版本兼容
nukemiko Dec 24, 2022
e89510d
改造了 `QMCv2` 使它和 2.0.x 版本兼容;`QMCv2.extra_info` 属性现在是可赋值和可删除的
nukemiko Dec 26, 2022
b54963d
修改了两处 `TypeError` 的错误信息
nukemiko Dec 26, 2022
53b823c
完成了对 KWM 相关功能的改造;增加了实验性的 KWM 文件导出功能
nukemiko Dec 30, 2022
bf28026
添加了 `probe_qmcv1()` 用于探测 QMCv1 文件、`probe()` 用于结合 QMCv1 和 QMCv2 的探测
nukemiko Dec 30, 2022
afd4867
为 `NCM`、`KWM`、`QMCv1`、`QMCv2` 在 `open()` 方法的第一个参数为元组的情况添加了更为严格的类型限制
nukemiko Dec 30, 2022
223aa61
Say Hello to 2023!
nukemiko Jan 4, 2023
82718c4
`KeyStreamBasedStreamCipherProto`:为 `keystream()` 添加了 `operation` 参数,…
nukemiko Jan 6, 2023
2c46af7
修改了提交 82718c4fa276d98f3a51887d423b4a8fcd10218e 遗漏的错误信息
nukemiko Jan 7, 2023
4b7d06d
修复了 `KeyStreamBasedStreamCipherSkel.decrypt()` 调用两个可选方法时缺少参数,导致 TypeE…
nukemiko Jan 12, 2023
c18d79f
完成了对 KGM/VPR 相关功能的改造;增加了实验性的 KGM/VPR 文件导出功能
nukemiko Jan 12, 2023
dafc6e8
完善了 `KWM` 和 `QMCv2` 的文档
nukemiko Jan 13, 2023
93f8c0c
完善了 `KGMorVPR` 的文档,并使其向后兼容
nukemiko Jan 13, 2023
218fbe9
暂时删除了示例脚本
nukemiko Jan 13, 2023
56fefd2
为 `KGMorVPR` 添加了 `new()` 方法
nukemiko Jan 13, 2023
7372e93
更新 README 和版本号
nukemiko Jan 13, 2023
61ad400
添加了 __all__
nukemiko Jan 13, 2023
fc14a8e
将 `*FileInfo` 加入了 `__all__`;修复了 `qmc.QMCv1.open()` 不正确的类型标注
nukemiko Jan 15, 2023
08034d3
重命名了所有的 `probe()` 函数以使它们更易于辨识
nukemiko Jan 15, 2023
784a11c
补充了遗漏的弃用警告,以及警告过滤器设置;现在 `QMCv1.to_file()` 和 `QMCv1.save()` 的 `filethi…
nukemiko Jan 18, 2023
b44f4e5
在包顶级目录的 __init__.py 添加了常用模块
nukemiko Jan 18, 2023
6e99e73
大幅更改 README
nukemiko Jan 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 nukemiko
Copyright (c) 2023 nukemiko

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
include src/libtakiyasha/qmc/binaries/*
recursive-include src/libtakiyasha/binaries/*
include MANIFEST.in src/libtakiyasha/VERSION
154 changes: 46 additions & 108 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,141 +1,79 @@
# libtakiyasha ![](https://img.shields.io/badge/Version-2.0.1-green) ![](https://img.shields.io/badge/Python-3.8%2B-blue)
# LibTakiyasha ![](https://img.shields.io/badge/Python-3.8%2B-blue)

`libtakiyasha` 是一个 Python 音频加密/解密工具库(当然也可用于加密非音频数据),支持多种加密文件格式。
LibTakiyasha 是一个 Python 音频加密/解密工具库(当然也可用于加密非音频数据),支持多种加密文件格式。**不提供任何命令行或图形界面支持。**

`libtakiyasha` 只是一个工具库,不提供任何命令行或图形界面支持。

---
## 使用前必读

**本项目是以学习和技术研究的初衷创建的,修改、再分发时请遵循 [License](LICENSE)。**

本项目的设计灵感,以及部分解密方案,来源于:

- [Unlock Music - Web Edition](https://git.unlock-music.dev/um/web)
- [jixunmoe/qmc2](https://github.com/jixunmoe/qmc2)
- [Unlock Music Project - CLI Edition](https://git.unlock-music.dev/um/cli)
- [parakeet-rs/libparakeet](https://github.com/parakeet-rs/libparakeet)

**本项目不会内置任何解密所需的密钥。你需要自行寻找解密所需密钥或加密参数,在调用时作为参数传入。**
**本项目没有所谓的“默认密钥”或“内置密钥”,打开/保存任何类型的加密文件都需要你提供对应的密钥。你需要自行寻找解密所需密钥或加密参数,在调用时作为参数传入。**

你可以在内容提供商的应用程序中查找这些必需参数,或寻求同类项目以及他人的帮助。**但请不要在 Issues/讨论区向作者索要所谓“缺失”的“内置密钥”,你的此类想法不会被满足。**
你可以<u>在内容提供商的应用程序中查找这些必需参数</u>,或<u>寻求同类项目以及他人的帮助</u>,**但请不要在 Issues/讨论区直接向作者索要所谓“缺失”的“内置密钥”。**

**`libtakiyasha` 对输出数据的可用性(是否可以识别、播放等)不做任何保证。**
**LibTakiyasha 对输出数据的可用性(是否可以识别、播放等)不做任何保证。**

---

## 特性

- 纯 Python 实现(包括所有依赖关系),无 C/C++ 扩展模块,跨平台可用
- 支持多种加密文件格式的加密和解密

## 当前版本:[2.0.1](https://github.com/nukemiko/libtakiyasha/releases/tag/2.0.1)

此版本为正式版,但仍有不完美之处。如果发现任何 `libtakiyasha` 自身的问题,欢迎[提交 Issue](https://github.com/nukemiko/libtakiyasha/issues)。

**`libtakiyasha` 2.x 版本和 1.x 版本之间的接口并不兼容,使用 1.x 版本的应用程序需要进行大量改造,才能使用 2.x 版本。**

另外,`libtakiyasha` 3.x 版本正在开发,有兴趣者可以切换分支查看。

### 支持的格式

请在[此处](https://github.com/nukemiko/libtakiyasha/wiki/%E6%94%AF%E6%8C%81%E7%9A%84%E6%A0%BC%E5%BC%8F%E5%92%8C%E6%89%80%E9%9C%80%E5%AF%86%E9%92%A5%E5%8F%82%E6%95%B0)查看。

### 兼容性

到目前为止(版本 2.0.1),`libtakiyasha` 已在以下 Python 实现中通过了测试:

- [CPython(官方实现)](https://www.python.org) 3.8 至 3.10,可能支持 3.11
- [Pyston](https://github.com/pyston/pyston) [2.3.5](https://github.com/pyston/pyston/releases/tag/pyston_2.3.5)(基于 CPython 3.8.12),其他版本或许也可用
- [PyPy](https://www.pypy.org/) 7.3.9([CPython 3.8 兼容版本、CPython 3.9 兼容版本](https://downloads.python.org/pypy/))

**注意:`libtakiyasha` 所需的最低 Python 版本为 3.8,因为它使用的很多 Python 特性从 Python 3.8 开始才出现,这意味着使用更低的 Python 版本会出现大量不可预知的错误。**

提示:在作者运行的测试中,CPython 实现是速度最慢的;PyPy 比 Pyston 快了大约两倍,比 CPython 快了接近五倍。

### 安装

- 运行命令:`pip install -U libtakiyasha==2.0.1`
- 或者前往 [GitHub 发布页](https://github.com/nukemiko/libtakiyasha/releases/tag/2.0.1) 下载安装

#### 所需依赖关系

- `pyaes` - AES 加解密支持
- `setuptools` - 安装依赖

如果你是通过[上文提到的方式](#安装)安装的 `libtakiyasha`,这些依赖会被自动安装。

### 基本使用方法

提取加密文件里的音频内容:

```python
from libtakiyasha.ncm import NCM
from libtakiyasha.qmc import QMCv2

... # 定义你提供的核心密钥 your_core_key、your_simple_key、your_mix_key1 和 your_mix_key2

# 打开 NCM 文件
ncmfile = NCM.from_file('source.ncm', core_key=your_core_key)
target_file_format = ncm.ncm_tag.format
- 使用纯 Python 代码编写
- **兼容 Python 3.8 及后续版本**,兼容多种 Python 解释器实现(见下文 [#性能测试](#性能测试))
- 易于阅读,方便 Python 爱好者学习
- (包括依赖库)无任何 C/C++ 扩展模块,跨平台性强

with open('target_from_ncm.' + target_file_format, mode='wb') as fd:
# libtakiyasha 的所有透明加密文件对象(NCM、QMCv1、QMCv2、KGMorVPR、KWM 等)默认以固定大小的块(io.DEFAULT_BUFFER_SIZE)为单位进行迭代
# 通过修改对象的 iter_mode 属性为 'line',可以使其以一行为单位进行迭代
# 不过按行迭代会导致性能大幅下降,不推荐使用
for block in ncmfile:
fd.write(block)
### 性能测试

# 打开 QMCv2 文件
qmcv2file = QMCv2.from_file('source.mflac', simple_key=your_simple_key)
target_file_format = 'flac'
由于 Python 语言自身原因,LibTakiyasha 相较于同类项目,运行速度较慢。因此我们使用不同解释器实现,对常用操作做了一些性能测试:

with open('target_from_mflac.' + target_file_format, mode='wb') as fd:
for block in qmcv2file:
fd.write(block)
| 操作 | 测试大小 | Python 3.10.9 (CPython) | Python 3.8.12 (Pyston 2.3.5) | Python 3.9.16 (PyPy 7.3.11) |
| :------------: | :------: | :---------------------: | :--------------------------: | :-------------------------: |
| NCM 加密 | 36.8 MiB | 4.159s | 2.159s | 1.366s |
| NCM 解密 | 36.8 MiB | 4.393s | 2.360s | 1.480s |
| QMCv1 加密 | 36.8 MiB | 3.841s | 2.116s | 1.594s |
| QMCv1 解密 | 36.8 MiB | 3.813s | 2.331s | 1.406s |
| QMCv2 掩码加密 | 36.8 MiB | 4.065s | 2.201s | 1.727s |
| QMCv2 掩码解密 | 36.8 MiB | 3.990s | 2.200s | 1.848s |
| QMCv2 RC4 加密 | 36.8 MiB | 12.820s | 5.596s | 2.717s |
| QMCv2 RC4 解密 | 36.8 MiB | 12.588s | 5.913s | 2.552s |
| KGM 解密 | 64.4 MiB | 49.014s | 22.053s | 8.376s |
| VPR 解密 | 87.9 MiB | 70.030s | 32.252s | 11.902s |

# 也可以打开来自 QQ 音乐 PC 客户端 18.57 及更新版本的 QMCv2 文件,
# 但需要正确的 mix_key1 和 mix_key2 参数
qmcv2file_keyencv2 = QMCv2.from_file('source.mflac', simple_key=your_simple_key, mix_key1=your_mix_key1, mix_key2=your_mix_key2)
target_file_format = 'flac'
仅在你对速度有要求时,可以考虑在调用 LibTakiyasha 时使用 PyPy/Pyston 解释器。

with open('target_from_mflac.' + target_file_format, mode='wb') as fd:
for block in qmcv2file_keyencv2:
fd.write(block)
```
一般情况下,建议使用官方解释器实现(CPython)。

- 打开加密文件时,如果不提供核心密钥,会报错而无法继续:
## 安装

```pycon
可用的最新版本:2.1.0rc1,可前往[发布页面](https://github.com/nukemiko/libtakiyasha/releases/tag/2.1.0rc1)或 [PyPI](https://pypi.org/project/libtakiyasha/2.1.0rc1/) 下载。

>>> from libtakiyasha import QMCv2
>>> qmcv2file = QMCv2.from_file('source.mflac')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
<...>
ValueError: 'simple_key' is required for QMCv2 file master key decryption
>>>
```
如果你要下载其他版本:

你需要向 `QMCv2.from_file()` 传入正确的 `simple_key` 参数才能打开文件。
- PyPI:https://pypi.org/project/libtakiyasha/#history ,挑选自己所需的版本,下载安装包,手动安装。
- 或者使用 pip 安装:`python -m pip install -U libtakiyasha==<你所需的版本>`
- 前往[发布页面](https://github.com/nukemiko/libtakiyasha/releases)挑选自己所需的版本,下载安装包,手动安装。

同样,你需要向 `NCM.from_file()` 传入正确的 `core_key` 参数才能打开 NCM 文件。
### 依赖项

生成加密文件(以 QMCv2 为例)
LibTakiyasha 依赖以下包,均可从 PyPI 获取

```python
from libtakiyasha.qmc import QMCv2
- [pyaes](https://pypi.org/project/pyaes/)
- [mutagen](https://pypi.org/project/mutagen/)

... # 定义你的 your_simple_key、your_mix_key1 和 your_mix_key2
## 常见问题

new_qmcv2 = QMCv2.new()
> 为什么 2.x 打开文件需要密钥,而 1.x 版本不需要?

new_qmcv2.simple_key = your_simple_key # 可选,但如果跳过此步骤,在保存到文件时需要填写参数 simple_key
这是出于以下考虑:

with open('plain.flac', 'rb') as fd:
for line in fd:
new_qmcv2.write(line)
- LibTakiyasha 是一个加解密库,当然需要为用户提供自定义密钥的权利
- 为了保护本项目不受美国<ruby>数字千年版权法<rt>Digital Millennium Copyright Act</rt></ruby>(DMCA)影响,避免仓库被误杀
- 因此,本仓库所有 1.x 及更早版本的提交和发布版本都已删除。

# 保存为 QMCv2 KeyEncV1
new_qmcv2.to_file('encrypted.mflac')
> 如何使用?

# 也可以保存为 QMCv2 KeyEncV2 - QQ 音乐 PC 端 18.57 及更高版本的格式
new_qmcv2.to_file('encrypted-keyencv2.mflac', master_key_enc_ver=2, mix_key1=your_mix_key1, mix_key2=your_mix_key2)
```
LibTakiyasha 的文档(DocStrings)写得非常清晰,你可以在导入后,使用 Python 内置函数 `help(<...>)` 查看用法。
Loading