mirror of
				https://github.com/Mabbs/mabbs.github.io
				synced 2025-11-04 04:15:18 +08:00 
			
		
		
		
	
		
			
	
	
		
			68 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			68 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								layout: post
							 | 
						|||
| 
								 | 
							
								title: Web Crypto Api学习笔记
							 | 
						|||
| 
								 | 
							
								tags: [学习笔记, Web Crypto Api]
							 | 
						|||
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								  感觉要爆炸了……<!--more-->    
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								# 学习前
							 | 
						|||
| 
								 | 
							
								  在四个月前,我作了[制作分布式加密邮件系统的计划](/2019/07/02/encmail.html),不过现在来看,这怕是得变成五年计划了……   
							 | 
						|||
| 
								 | 
							
								  Javascript是真的垃圾,搞一堆对象,各种各样的对象让人无言以对,不过也可能因为我以前用的是Linux Shell语言,那个语言在我学了Python之后还是感觉很舒服,因为它不用管变量类型,Bash之类的解析器会把它们一律看作字符串,遇到要运算的部分才会转换为数字。除此之外,它连接字符串是什么都不用加,不需要考虑变量是什么类型,只要解析器能分辨变量,它就能正常工作,也不需要什么强制转换之类乱七八糟的东西,而且它更没有什么乱七八糟的对象之类的概念。 ~~(跑题了:-P)~~   
							 | 
						|||
| 
								 | 
							
								  不过浏览器只支持Javascript语言……没办法,看来只能动用我的Copy&Paste大法了。不过国内用Web Crypto Api的人好少,找了半天也没有什么示例可以Copy……没办法,那我只好去抄[官方示例](https://mdn.github.io/dom-examples/web-crypto/)了……    
							 | 
						|||
| 
								 | 
							
								  
							 | 
						|||
| 
								 | 
							
								# 学习过程
							 | 
						|||
| 
								 | 
							
								  我在大学中也加了那么一个社团/协会,在社团办公室里虽然没人能帮助我学习Javascript,不过那里有多余的屏幕!然后我就体验了一下双屏幕工作的感觉,那个感觉还是挺不错的(也可能是我的屏幕分辨率太低了,是1366x768的垃圾屏幕……)一个屏幕打代码,另一个看网页效果,还是挺不错的,至少不用不停的切换窗口了。   
							 | 
						|||
| 
								 | 
							
								  看着示例代码,我感觉真是要爆炸了,各种奇葩的对象,像什么ArrayBuffer还是什么Uint8Array啥的,还有一堆乱七八糟要求的格式,密码长度还必须是16的倍数?而且还有什么初始向量iv……真的是一言难尽……   
							 | 
						|||
| 
								 | 
							
								  不过我还是发挥了作为辣鸡程序员的特长——Copy&Paste大法,最终可算是拼凑出了一个看起来勉强能用的代码……
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# 辣鸡代码
							 | 
						|||
| 
								 | 
							
								```js
							 | 
						|||
| 
								 | 
							
								function getByteLen(val) {
							 | 
						|||
| 
								 | 
							
								    var len = 0;
							 | 
						|||
| 
								 | 
							
								    for (var i = 0; i < val.length; i++) {
							 | 
						|||
| 
								 | 
							
								        if (val[i].match(/[^\x00-\xff]/ig) != null) len += 3;
							 | 
						|||
| 
								 | 
							
								        else len += 1;
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								    return len;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								  function importSecretKey(rawKey) {
							 | 
						|||
| 
								 | 
							
								    return window.crypto.subtle.importKey(
							 | 
						|||
| 
								 | 
							
								      "raw",
							 | 
						|||
| 
								 | 
							
								      rawKey,
							 | 
						|||
| 
								 | 
							
								      "AES-GCM",
							 | 
						|||
| 
								 | 
							
								      true,
							 | 
						|||
| 
								 | 
							
								      ["encrypt", "decrypt"]
							 | 
						|||
| 
								 | 
							
								    );
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								  async function encryptMessage(key) {
							 | 
						|||
| 
								 | 
							
									iv = window.crypto.getRandomValues(new Uint8Array(12));
							 | 
						|||
| 
								 | 
							
								    ciphertext = await window.crypto.subtle.encrypt(
							 | 
						|||
| 
								 | 
							
								      {
							 | 
						|||
| 
								 | 
							
								        name: "AES-GCM",
							 | 
						|||
| 
								 | 
							
								        iv: iv
							 | 
						|||
| 
								 | 
							
								      },
							 | 
						|||
| 
								 | 
							
								      key,
							 | 
						|||
| 
								 | 
							
								      encoded
							 | 
						|||
| 
								 | 
							
								    );
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								console.log(ciphertext)
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								    let secretKey;
							 | 
						|||
| 
								 | 
							
								const enc = new TextEncoder();
							 | 
						|||
| 
								 | 
							
								keyword="Mayx"
							 | 
						|||
| 
								 | 
							
								    while (getByteLen(keyword) % 16 != 0) {
							 | 
						|||
| 
								 | 
							
								        keyword = keyword + "\0";
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								const rawKey = enc.encode(keyword);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								const encoded = enc.encode("Mayx is Good");
							 | 
						|||
| 
								 | 
							
								(async () => {
							 | 
						|||
| 
								 | 
							
								    secretKey = await importSecretKey(rawKey);
							 | 
						|||
| 
								 | 
							
									encryptMessage(secretKey);
							 | 
						|||
| 
								 | 
							
								})();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# 感想
							 | 
						|||
| 
								 | 
							
								  路漫漫其修远兮,吾将上下而求索,我还是要继续加油啊!
							 |