首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用java代码实现动态加密/解密

用java代码实现动态加密/解密
EN

Stack Overflow用户
提问于 2021-12-27 20:17:14
回答 2查看 667关注 0票数 0

我正在尝试用flutter创建一个应用程序,我的示例代码是用java编写的。

下面是示例java代码gist https://gist.github.com/kapiljhajhria/72a22ff75e238878f539f7bb21026208

这是我的颤振代码gist https://gist.github.com/kapiljhajhria/795d1a7c7cf1c76ca8e327bf8b2f51de

以下是我正在做的事情的简要总结

  1. 生成唯一的会话密钥: AES随机密钥256
  2. 使用步骤1中的会话密钥加密JSON数据
  3. 生成JSON数据的SHA256散列
  4. 使用步骤1中的会话密钥加密从步骤3生成的散列。
  5. 使用公钥加密会话密钥。公钥作为certificate.cer文件提供。我复制字符串值并将其作为常量添加到类中,以使其更易于使用。不确定这是否是最好的方法。
  6. 创建带有3个参数的POST请求。如java代码所示。我想我把这部分做对了。
  7. 我将得到的响应将使用步骤1中的会话密钥进行加密,因此我必须解密该响应数据。还没走到这一步。

我无法访问发出此请求的服务器。由于post请求是使用web视图进行的,所以我无法从请求中找到正确的错误。我得到的只有网页,上面写着“无效请求”

因此,我的第一个猜测是,我没有正确地使用公钥加密我的会话密钥。如果这部分是正确的,那么我就没有正确地加密数据,或者我的加密方法与java代码中使用的加密方法不匹配。也许我正在生成的会话密钥是不正确的。

任何帮助都将不胜感激。谢谢。如果你需要我的帮助,请告诉我。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-05 03:33:45

我使用这个文档作为我的参考:https://developers.emsigner.com/signer-gateway/api-reference/signing-documents.html

您需要两个包:pointycastlex509,并按如下方式导入它们:

代码语言:javascript
复制
import 'package:pointycastle/export.dart';
import 'package:x509/x509.dart';

然后,您需要这些帮助函数:

代码语言:javascript
复制
Uint8List generateSessionKey() {
  final r = Random();
  return Uint8List.fromList(List<int>.generate(32, (_) => r.nextInt(256)));
}

RSAPublicKey parseCert(String pemData) {
  final cert = parsePem(pemData).first as X509Certificate;
  final pub = cert.publicKey as RsaPublicKey;
  return RSAPublicKey(pub.modulus, pub.exponent);
}

Uint8List encryptUsingPublicKey(RSAPublicKey key, Uint8List data) {
  final cipher = PKCS1Encoding(RSAEngine())
    ..init(true, PublicKeyParameter<RSAPublicKey>(key));
  return cipher.process(data);
}

Uint8List encryptUsingSessionKey(Uint8List key, Uint8List data) {
  final cipher = PaddedBlockCipher('AES/ECB/PKCS7')
    ..init(true, PaddedBlockCipherParameters(KeyParameter(key), null));
  return cipher.process(data);
}

Uint8List sha256Digest(Uint8List data) {
  return SHA256Digest().process(data);
}

你可以像这样构建你的3个参数:

代码语言:javascript
复制
  final pem = File('cert2.pem').readAsStringSync();
  final publicKey = parseCert(pem);

  final sessionKey = generateSessionKey();

  final encryptedSessionKey = encryptUsingPublicKey(publicKey, sessionKey);

  final jsonString = json.encode(<String, dynamic>{
    'FileType': 'PDF',
    'SignaturePosition': 'Top-Left',
    'AuthToken': 'some token',
    'File': '',
    'SUrl': 'http://localhost:3000/Success',
    'FUrl': 'http://localhost:3000/Error',
    'CUrl': 'http://localhost:3000/Cancel',
    'ReferenceNumber': 'generate unique reference number',
  });

  final jsonBytes = utf8.encode(jsonString) as Uint8List;

  final encryptedJson = encryptUsingSessionKey(sessionKey, jsonBytes);

  final hash = sha256Digest(jsonBytes);
  final encryptedHash = encryptUsingSessionKey(sessionKey, hash);

  final p1 = base64.encode(encryptedSessionKey);
  final p2 = base64.encode(encryptedJson);
  final p3 = base64.encode(encryptedHash);

但是,我看到的最大问题是你怎么写这篇文章,因为你想在网页上,对吗?而普通的颤振网页视图不支持初始发布。看起来好像还有另一个包裹。只需搜索flutter webview post

顺便说一句,如果您不想使用切入点注册表,您可以重写encryptUsingSessionKey,而不需要这样做:

代码语言:javascript
复制
  final cipher = PaddedBlockCipherImpl(
    PKCS7Padding(),
    ECBBlockCipher(AESEngine()),
  )..init(true, PaddedBlockCipherParameters(KeyParameter(key), null));
  return cipher.process(data);

最后,至少在您理解web视图问题之前,您可以只使用http来发布文章。但是,让它完成编码参数和设置内容类型的工作,如下所示:

代码语言:javascript
复制
  final response = await http.post(
    Uri.parse('https://somewhere/V3_0/Index'),
    body: <String, String>{
      'Parameter1': p1,
      'Parameter2': p2,
      'Parameter3': p3,
    },
  );
  print(response.statusCode);
  print(response.body);
票数 1
EN

Stack Overflow用户

发布于 2021-12-31 09:57:55

看看这个项目,它是一个加密示例,附带了一个很好的文档,有3种类型的加密:

  1. AES加密
  2. Fernet加密
  3. Salsa20加密
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70500029

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档