如果對密碼學(xué)還不了解飞醉,可以先看一下現(xiàn)代密碼學(xué)程序猿補(bǔ)完計(jì)劃
Tikn是什么
由Google的密碼學(xué)家和安全工程師聯(lián)合編寫的加密庫科盛。源于與Google產(chǎn)品團(tuán)隊(duì)合作的豐富經(jīng)驗(yàn)眠寿,提供了即便沒有加密經(jīng)驗(yàn)也可以安全使用的API暂刘。
Github地址
優(yōu)勢
- 多語言跨平臺,以往我們在同種開發(fā)言語下加解密還好說,但多語言甚至跨平臺時(shí)就很麻煩了凭迹。例如用C#做RSA加密再用Java解密摊聋,如果沒有點(diǎn)加密功底,絕對夠你弄上好幾天的璧瞬。
- 另一個(gè)就是易用性户辫,整套API結(jié)構(gòu)清晰,用起來簡單高效嗤锉。
使用場景
- 各種開發(fā)語言混合加解密渔欢,甚至跨平臺;
- 如果你的項(xiàng)目是Java并基于Springcloud瘟忱,那么自己編寫一個(gè)tink的starter真是再好不過了奥额;
- 與你的KMS(key management systems)結(jié)合使用苫幢;
一個(gè)簡單的例子
先引入tink,最新版是1.2.0垫挨;
<dependency>
<groupId>com.google.crypto.tink</groupId>
<artifactId>tink</artifactId>
<version>1.2.0</version>
</dependency>
安卓可以使用Gradle引入tink韩肝;
dependencies {
compile 'com.google.crypto.tink:tink-android:1.2.0'
}
- AES的加解密例子
import com.google.crypto.tink.Aead;
import com.google.crypto.tink.KeysetHandle;
import com.google.crypto.tink.aead.AeadFactory;
import com.google.crypto.tink.aead.AeadKeyTemplates;
import com.google.crypto.tink.config.TinkConfig;
import java.io.IOException;
import java.security.GeneralSecurityException;
public class TinkDemo {
public static void main(String[] args) throws GeneralSecurityException, IOException {
// 基于默認(rèn)配置進(jìn)行注冊
TinkConfig.register();
// 測試用的明文字符串
String plaintext = "技術(shù)學(xué)徒";
// 生成密鑰
KeysetHandle keysetHandle = KeysetHandle.generateNew(
AeadKeyTemplates.AES128_GCM);
Aead aead = AeadFactory.getPrimitive(keysetHandle);
/*
* 加密
* 第一個(gè)參數(shù)是plaintext(明文)
* 第二個(gè)參數(shù)是associatedData(相關(guān)數(shù)據(jù))
* 可以為null,相當(dāng)于一個(gè)空(零長度)字節(jié)數(shù)組九榔。
* 同樣哀峻,解密時(shí)必須提供同樣的相關(guān)數(shù)據(jù)。
*/
byte[] ciphertext = aead.encrypt(plaintext.getBytes(), null);
// 解密
byte[] decrypted = aead.decrypt(ciphertext, null);
System.out.println(new String(decrypted));
}
}
什么是 associatedData(相關(guān)數(shù)據(jù))哲泊?
應(yīng)該被認(rèn)證但未加密的數(shù)據(jù)剩蟀,具有相關(guān)數(shù)據(jù)的加密確保了該數(shù)據(jù)的真實(shí)性(即,發(fā)送者是誰)和完整性(即切威,數(shù)據(jù)未被篡改)育特,而不是其保密性(參見RFC 5116)
舉個(gè)栗子:你要對手機(jī)號加密,那么可以將用戶名作為相關(guān)數(shù)據(jù)先朦。
明文和相關(guān)數(shù)據(jù)可以有任意長度(在0..232字節(jié)范圍內(nèi))
我們注意到在加密之前有這么一句話:
Aead aead = AeadFactory.getPrimitive(keysetHandle);
Primitive 是什么缰冤?
Primitive 稱之為原語,Tink的所有加密都是通過原語來執(zhí)行的喳魏。上面代碼中返回的Aead就是原語中的一種锋谐,后面的文章我會介紹更多原語(也就是更多加密類型)。
Primitive 的特點(diǎn)截酷?
- 無狀態(tài)(stateless)涮拗,所以線程安全;
- copy-safe(參數(shù))迂苛;
- 至少128位安全性(RSA除外)三热;
后續(xù)文章我會逐步深入介紹常用加密的實(shí)現(xiàn)方法和部分源碼解讀。