使用公钥加密flutter中的数据

问题描述 投票:0回答:1

我需要在flutter中创建以下代码,使用RSAES-OAEP/SHA-256/MGF1-SHA-1用公钥加密数据

textPayPass=document.getElementById('tpassword').value;
$('tpassword').val('');
s_cert = "-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5xdSrXnpj8pUFBWvEWuEPmzL/iuCfoHwGsMou4PE5Y/wNmnM1E8niUww8yjLHgdOBOtPtLaBua/dkL+EKVXLylt0xpKtCC6KWBr07bvNK/CNXFUhd/9MMyV90UWJP5XHSzrxYz//ZJYn0XUicsKPDox7TJZFtMnw+euAwPDA7VhRupc4x8QHTkdTORUaeKSI3jLr6LdQC19BjeC5M4uZ45/U+6Hd9PPgKqp90dXrIyOcMXb65HrQoba6FsZnrN6qr7Z/4v4r6Xxdxo9Qwl6YBZJ3+1RlT/uSxjcxJTYgIropjI3O3r90+e7/DxE1ITHxxEjZhUkySTUBOkzeQdpRmHyL+ctSDvip7IO3Fd+axVvhSZq5w9x5DDWJcMhTiJpkjF3LHXaB1+T+oet36ClyMGmnnsnyOZ2s/kWiAaGFmqBebtk6iDkbq0y6hKtpNmPrx5hoUiQomo/cfoDpfnIUeJd4Kf+QRvTqGXP2yXbu8861LjWuaJ+kyTDUAoGV/Haw28P/Kwnr7oZTtP0mWU7bKqrPwoWAc9CHv2SKy4qjZCuS036VaAe2vd5gmGBni4hjA8YdWrLcPF5LwSDWoaXpPm9Ve8KB+5XpxLjyCjve/8y+9yGDtoYpTltOTsm9Au7BcZSFy5XyEAs6CQHaOZ6NGp8pIEhskUj7fv7/E6owkEMCAwEAAQ==-----END PUBLIC KEY-----";

var s_certForge = forge.pki.publicKeyFromPem(s_cert);
// encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1
// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
var encData = s_certForge.encrypt(textPayPass, 'RSA-OAEP', {
md: forge.md.sha256.create(),
mgf1: {
    md: forge.md.sha1.create()
}
});
var s_encData = forge.util.encode64(encData);

我的颤振代码

static String publicKeyTE ='''-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgsOgXZqI0joBljDjJ/9lOIHP1kGZJg8JsulkxK3CWOis/BO0N7Lqj70qGb8T3dgd/MOb/mmBkwxZ/U/PAIUS9YynPPPOd4ROXpEnkWYj5ntMKr7KWY/VKHSm+RzLWX8yi+8NmmK3NJosWzOXAwMIKY8ZSB+BBw//uI+aaRQlE4bAICufff9KcoJd8EEldQgLa74F+TgLg5VtV+2Ik9xgV2h2NaM6wvldp69OicjEgGPnX2uEwYJbo2HYiGjm5HnFtT70c5w8vO88O5/OvYafNfLmXZsszR/JYdPpOdKOf45NX2v50V43VnBgVlskki70kZAdi5roLjEpSC2vxjbh9I3dJrApp7UgnTE6+iaJg7onsXuXe1VPgp0evKM/BpVo2Jb95uD24oBop1OghQX6UyKYr7MAaPT3yT40vBOe5BxiAjbHDob/K8tzWt6fh1qKkLNry5jWOD/pQC7yrEBLIezB/Hzai+cIfBLqgWBEc1uA0D4/81SBu7MXTko1ne9HNF2zQwPtQOk0l/F8YOdCpyv4X0vxejc4pIwE+Iuk+KGqXvzRp2RnQZ6U08Bc4kkxXoEYSJ9ICyxSQCVxzJ9AMW8mlAOon71ZVr4ZWj9dicoQDUt+kXZV2E3itoy0guIabyk12ONvEekgzoRyRnrIv+mHWw6sV2Luo8bUh159sIsCAwEAAQ==-----END PUBLIC KEY-----''';

String encryptPassword(String password) {
RSAPublicKey publicKey=RsaKeyHelper().parsePublicKeyFromPem(publicKeyTE);
    final encrypter = Encrypter(
    RSA(
      publicKey: publicKey,
      encoding: RSAEncoding.OAEP,
      digest: RSADigest.SHA256,
    )
);
final encrypted = encrypter.encrypt(password);
return encrypted.base64;

}

我不知道我可能会丢失什么,但是当我加密密码并将其发送到服务器时,它看起来不正确。你能帮我看看我缺少什么吗?

flutter dart encryption password-encryption
1个回答
0
投票

对于 OAEP,必须指定各种参数,包括 OAEP 摘要和掩码生成函数(参见RFC 8017)。虽然后者原则上是可配置的,但实际上总是使用 MGF1 功能。 MGF1 本身有一个摘要作为参数,因此在 OAEP 上下文中实际上需要指定两个摘要,即 OAEP 摘要和 MGF1 摘要。
虽然原则上可以不同地指定两个摘要,但实际上,在这两种情况下通常应用相同的摘要。您的示例并非如此,其中 SHA256 用于 OAEP 摘要,SHA-1 用于 MGF1 摘要。

加密包(实际上只是一些PointyCastle功能的包装)不允许使用不同的摘要。
更强大的 PointyCastle 库也被设计为默认使用相同的摘要:MGF1 摘要存储在属性

OAEPEncoding#mgf1Hash
中,但使用
OAEPEncoding#init()
中的 OAEP 摘要隐式初始化。
但是,如果在
mgf1Hash
调用之后立即重新初始化 init() 参数,则重新初始化的值将用于进一步处理。通过这种方式,PointyCastle 允许为 OAEP 和 MGF1 摘要指定不同的摘要。
示例实现(示例密文是使用node-forge代码生成的):

import 'dart:convert'; import 'dart:typed_data'; import 'package:basic_utils/basic_utils.dart'; import 'package:pointycastle/export.dart'; ... String privatePem = '''-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCynSxDzTtiAX4s aLf70EIIFS2SoNnISjtQdzkLgu5btj5A49MvhzQ19JuIJkM2fSalCSyaccyuPqiY X4UW23OVdI29cw5N95LY1gkXjthxpWxCof/v1xJtsY+6qOvR/c7OWcPJYM5zhZu1 sT8WJLc5kHbOxnyCdVua47348aZqiByU0ZRNCK3n8j8iQI56N3CbBz/M/JPKdqDd SxOgZWIGxIMS62bUvDL0SZ0Y/EDuMWAs3JH0f8ToExit7Lx3l5WG+H9CslUHnw39 GTFTTimbyIawM8ffDQjiP2B0hJVORYcVa+ipy6VRXrsUjKUQUyy0ybtr9iEQR4eI imUy5GVbAgMBAAECggEAGYw9rp0GZ2hLQdLgrhYFu947nIOBYxKrFUFYWXsq2Ndi ZCmyJVQzdZw9OuYuKvcPtf9v789jNXEk8FaJVNGi4LfBJl30p9ZHnNhQiJwX/Xlp 2MYPM6ERs7r4Efzjbi/dispwJLfCD+gGc6Cco3Aw/Pza4YymdoqOxcLZg2gdI5OD RwOZrmfbrroFrIgvB8AzOsc4EBVf/F0BA7JotWh9GyX2h8DiYtpd2NOCxjUar6GF w+B76F9TYgHMexuluUe0Gi1J35yZqRR+ySSSuDCQNSOZFZ0UIP2KFhu+Vl2BbTJv glbujfT/iLNBtDlxpznJJqbH908tfqmXVD2wLq5tUQKBgQDWDiXCf/6B4YXKz2zg sCBPDkSLmJFv618SzjlZvfk+AYBgbCrk0hOuI7snb+XCuZVg9XnhIwyFM9OXwDET as9nwxh3mVluSmpkNm3MgWYQvYbqtfXn/VTQk8HZZVtjx2c5UO1ENj7pd1u0OrQY /jgqUL7yeTkWjUHprHAZv/LAtQKBgQDVnSZ5pTwlZnPDLbCSGWsbycIGiO4Bd/Gq jQlptWIvnBhW7f3JZ6DoWlLTjvu0iA/OWT4aC7/w2i0VadMDvz0GqTzTlbnexf7B +3L52tRCcQX1hRRDA3u6JV3kEpsweEnwWP39ZtXv924Ru/4S6DpZtwKvOFi9AvcI lxdHc6MnzwKBgQCijDXCYH39VSvLWf6dFUJDplsJAr+WlM8qsa29Z1To8Czzi9B6 2MiXGY0aoo+AcntsGJ0ICRyN3lBU0V6zFw4PBokC8VGHPj1Sgj6Y6L6AAdx9SdZF 6AtLJJk1JBHlUFwjmz/B58uYcMoTr+xpekteXtjRuppOdNBTyV2LQEbwbQKBgDmt 1VXDaBoxL9Dj5WmNs34tXFanYpzC5l5G9uO0Nm7kly3h1UUs1iXnPbYiRZTZqGrv bfVadtlyD/pYOMIqQTArQmFfbHDaxY9bdhBBJk9KdXF2HaJ6rk31CQUsgPr1gAGG Bg8GVX4WMYJYYKJ6UkcnQ3JMpKlkw49uPLruXn/BAoGANCI+9Q26Gd395Wu0ZcjO 0yr4INfx8ilrFiyjf1KpLC2G6kmL78zQrQP1I344Yplu9eJllDtj4AmxPa+/bCQz VN4DOnDY3599CLvG74f/oA0jB4jQB+vfMcTt5QNhvLQeWxhV5CRna36S//5Y9eab 8Xh1UaEAkxxVwUjUDCasMhs= -----END PRIVATE KEY-----'''; const ciphertextB64 = "m1nvGHz3RohBU40YWbWv0hDUghpLSdQxXzoQ9N0Tz2yMXDSYWEZLZ2L62x7x5ghTobUx3iHi1Rnsybs+ybmV2kt35YUfWe5/D3TpsvREBe0Bz2JaZveuPyE28iOe5w4BwCxd8rvakbmlbxdIx0T6SSRIvR/nq1qBhQfeIlJxjEnySi37Rk8cF5ci6FBQniWrF+n7HR/nRmPJKuwZ+EAYPmSgGDYXvyU73rOF/gn/ADlB8Is6cKA0JCadn16hJNLLpR68wur0yhcrR8LPlz5t4x5cfsWkI8vLsfdmtmSfAXcQgGp+guwAKQh275Rju+SlSMwql7BYRNYeAcuYNMKNHQ=="; final Uint8List ciphertext = base64Decode(ciphertextB64); final RSAPrivateKey privateKey = CryptoUtils.rsaPrivateKeyFromPem(privatePem); final OAEPEncoding oaepEncoding = OAEPEncoding.withSHA256(RSAEngine()); // specify SHA-256 as OAEP digest final PrivateKeyParameter<RSAPrivateKey> privateKeyParams = PrivateKeyParameter(privateKey); oaepEncoding.init(false, privateKeyParams); // initializes MGF1 digest with OAEP digest hash oaepEncoding.mgf1Hash = SHA1Digest(); // overwrite initialization and specify SHA-1 as MGF1 digest final Uint8List plaintext = oaepEncoding.process(ciphertext); final String plaintextStr = utf8.decode(plaintext); print(plaintextStr);

这成功解密了使用节点伪造代码生成的密文。

© www.soinside.com 2019 - 2024. All rights reserved.