长话短说,以下 java 和 obj-c 代码一起工作。
爪哇:
import com.google.crypto.tink.aead.AeadConfig;
import com.google.crypto.tink.*;
byte[] plainData = ...
byte[] key = ...//32 bytes
byte[] aad = ...
AeadConfig.register();
byte[] preffix = {0x1a,0x20};
byte[] fullKey = new byte[preffix.length + key.length];
System.arraycopy(preffix, 0, fullKey, 0, preffix.length);
System.arraycopy(key, 0, fullKey, preffix.length, key.length);
String fullKeyBase64 = new String(com.groups.network.aes.Base64.encode(fullKey), "UTF-8");
String jsonKey = "{\"primaryKeyId\":1635322858,\"key\":[{\"keyData\":{\"typeUrl\":\"type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key\",\"value\":\""+fullKeyBase64+"\",\"keyMaterialType\":\"SYMMETRIC\"},\"status\":\"ENABLED\",\"keyId\":1635322858,\"outputPrefixType\":\"TINK\"}]}";
KeysetHandle keysetHandle = CleartextKeysetHandle.read(
JsonKeysetReader.withString(jsonKey));
Aead aead = keysetHandle.getPrimitive(Aead.class);
byte[] encrypted = aead.encrypt(plainData, aad);
目标 C:
NSData* encryptedBytes = ...
NSData* aad = ...
NSData* key = ...//32-bytes
NSError *error = nil;
TINKAeadConfig *aeadConfig = [[TINKAeadConfig alloc] initWithError:&error];
if (!aeadConfig || error) {
//handle error
}
if (![TINKConfig registerConfig:aeadConfig error:&error]) {
//handle error
}
NSString* preffix = @"1a20";
NSMutableData* preffixData = [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i;
for(i=0; i<[preffix length]/2;i++){
byte_chars[0] = [preffix characterAtIndex:i*2];
byte_chars[1] = [preffix characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[preffixData appendBytes:&whole_byte length:1];
}
NSData* originalKeyData = [key dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* finalKey = [preffixData mutableCopy];
[finalKey appendData:originalKeyData];
NSString* jsonTmp = [NSString stringWithFormat:@"{\"primaryKeyId\":1635322858,\"key\":[{\"keyData\":{\"typeUrl\":\"type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key\",\"value\":\"%@\",\"keyMaterialType\":\"SYMMETRIC\"},\"status\":\"ENABLED\",\"keyId\":1635322858,\"outputPrefixType\":\"TINK\"}]}", [finalKey base64Encoding]];
NSData* jsonKeyData = [jsonTmp dataUsingEncoding:NSUTF8StringEncoding];
TINKJSONKeysetReader *reader = [[TINKJSONKeysetReader alloc] initWithSerializedKeyset:jsonKeyData error:&error];
if (!reader || error) {
//handle error
}
TINKKeysetHandle *handle = [[TINKKeysetHandle alloc] initCleartextKeysetHandleWithKeysetReader:reader error:&error];
if (!handle || error) {
//handle error
}
id<TINKAead> aead = [TINKAeadFactory primitiveWithKeysetHandle:handle error:&error];
if (!aead || error) {
//handle error
}
NSData *aadData = [aad dataUsingEncoding:NSUTF8StringEncoding];
NSData *plaintext = [aead decrypt:encryptedBytes withAdditionalData:aadData error:&error];
if (!plaintext || error) {
//handle error
}
注意 {0x1a,0x20}。这会根据您使用的加密类型而变化(这里适用于 XChacha20-Poly1305)。这可以用Tinkey工具“发现”,如果你运行类似java -jar tinkey_deploy.jar create-keyset --key-template XCHACHA20_POLY1305
的东西,它会输出一个 JSON 密钥模板(输出 base64 密钥需要然后转换为字节,你需要确定前 2 个字节对应于哪个加密)