在客户端用forgejs加密数据,用ruby解密
Encrypting data with forgejs on the client side, and decrypting with ruby
对于给定的项目,我希望使用 AES 256 加密一段数据,然后使用 RSA 加密密钥。我一直在 ruby 中使用 Forge 和加密器 gem,但我似乎无法获得匹配的加密值:
var key = 'strengthstrengthstrengthstrength';
var iv = 'cakecakecakecakecakecakecakecake';
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer("some string"));
cipher.finish();
var encrypted = cipher.output;
console.log(btoa(encrypted.data)); // outputs: CjLmWObDO2Dlwa5tJnRBRw==
然后在 IRB 中:
Encryptor.encrypt 'some string', :key => 'strengthstrengthstrengthstrength', :key => 'cakecakecakecakecakecakecakecake'
Base64.encode64 _
# outputs: C9Gtk9YfciVMJEsbhZrQTw==\n
在密钥和 IV 中使用字符串值,尝试过:
var key = forge.random.getBytesSync(32);
var iv = forge.random.getBytesSync(32);
然后对他们每个人进行 btoa()
调用。在 ruby 端使用 Base64.decode64
,然后将它们传递给 Encryptor.decrypt
,但仍然没有成功。
知道我哪里出错了吗?
我设法让它工作了。因为我只是使用一个密钥来加密一个值,所以我也只是将密钥用作 IV & Salt。 如果您使用密钥加密多个值,则不建议这样做。然后您将需要生成适当的盐和 iv 值。
此外,gen 密钥值是一种非常糟糕的方式,因为 Math.random
不安全。只是 运行 没时间正确执行此操作,但在这种情况下工作正常。
var Encryption = (function () {
var api = {
getKey: function () {
var possible = "ABCDEFabcdef0123456789";
var key = '';
for (var i = 0; i < 32; i++) {
key += possible.charAt(Math.floor(Math.random() * possible.length));
}
return key;
},
encryptPII: function (rawKey, value) {
var salt = rawKey;
var iv = rawKey;
var key = forge.pkcs5.pbkdf2(rawKey, salt, 2000, 32);
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer(value));
cipher.finish();
return btoa(cipher.output.data);
}
};
return api;
})();
rawKey
是从getKey()
返回的值。 value
属性 是要加密的字符串。我将 rawkey 用于 iv 和 salt 值,生成密钥的方式与 ruby 中的 Encryptor gem 相同。然后使用 forge 加密字符串值。
如果我使用 base64,在 ruby 中对其进行解码,并将相同的 rawKey
值传递给密钥、盐和 iv 的加密器 gem,它就可以工作。
对于给定的项目,我希望使用 AES 256 加密一段数据,然后使用 RSA 加密密钥。我一直在 ruby 中使用 Forge 和加密器 gem,但我似乎无法获得匹配的加密值:
var key = 'strengthstrengthstrengthstrength';
var iv = 'cakecakecakecakecakecakecakecake';
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer("some string"));
cipher.finish();
var encrypted = cipher.output;
console.log(btoa(encrypted.data)); // outputs: CjLmWObDO2Dlwa5tJnRBRw==
然后在 IRB 中:
Encryptor.encrypt 'some string', :key => 'strengthstrengthstrengthstrength', :key => 'cakecakecakecakecakecakecakecake'
Base64.encode64 _
# outputs: C9Gtk9YfciVMJEsbhZrQTw==\n
在密钥和 IV 中使用字符串值,尝试过:
var key = forge.random.getBytesSync(32);
var iv = forge.random.getBytesSync(32);
然后对他们每个人进行 btoa()
调用。在 ruby 端使用 Base64.decode64
,然后将它们传递给 Encryptor.decrypt
,但仍然没有成功。
知道我哪里出错了吗?
我设法让它工作了。因为我只是使用一个密钥来加密一个值,所以我也只是将密钥用作 IV & Salt。 如果您使用密钥加密多个值,则不建议这样做。然后您将需要生成适当的盐和 iv 值。
此外,gen 密钥值是一种非常糟糕的方式,因为 Math.random
不安全。只是 运行 没时间正确执行此操作,但在这种情况下工作正常。
var Encryption = (function () {
var api = {
getKey: function () {
var possible = "ABCDEFabcdef0123456789";
var key = '';
for (var i = 0; i < 32; i++) {
key += possible.charAt(Math.floor(Math.random() * possible.length));
}
return key;
},
encryptPII: function (rawKey, value) {
var salt = rawKey;
var iv = rawKey;
var key = forge.pkcs5.pbkdf2(rawKey, salt, 2000, 32);
var cipher = forge.aes.createEncryptionCipher(key, 'CBC');
cipher.start(iv);
cipher.update(forge.util.createBuffer(value));
cipher.finish();
return btoa(cipher.output.data);
}
};
return api;
})();
rawKey
是从getKey()
返回的值。 value
属性 是要加密的字符串。我将 rawkey 用于 iv 和 salt 值,生成密钥的方式与 ruby 中的 Encryptor gem 相同。然后使用 forge 加密字符串值。
如果我使用 base64,在 ruby 中对其进行解码,并将相同的 rawKey
值传递给密钥、盐和 iv 的加密器 gem,它就可以工作。