UE4中Crypto++库加密解密

第五节:RSA签名解签 - 前端JSEncrypt库、jsrsasign库和后端UE4使用Crypto++互相加解签


文章目录

  • UE4中Crypto++库加密解密
  • 前言
  • 一、前端
  • 二、后端
    • 1. C++代码
    • 2. 蓝图
  • 测试结果
  • 总结
  • 参考

前言

后端签名,前端解签,或者前端加签,后端解签。后端事先生成公钥和私钥,公钥发给前端页面,私钥后端自己保留。非对称加密算法常用RSA算法,签文使用base64编码成字符串,后端UE4使用Crypto++库,前端使用JSEncrypt.js或者jsrsasign.js进行RSA的对应操作。经过测试,本例中的前后端代码的加签解签计算结果是一致的。


提示:以下是本篇文章正文内容,下面案例可供参考

一、前端

前端html分别使用JSEncrypt库和jsrsasign库写两个函数,一个是加签函数,使用私钥加签字符串并将签文发送到后端进行解签。另一个是解签函数,需要接收后端发来的签文,并使用公钥验证签文。

<script src="./crypto-js.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jsencrypt/3.2.1/jsencrypt.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jsrsasign/10.5.13/jsrsasign-all-min.min.js"></script><script type = "text/javascript">
//签名function RsaSign(plainText){var signStr = new JSEncrypt();//设置私钥// signStr.setPrivateKey('-----BEGIN RSA PRIVATE KEY-----'+privKey+'-----END RSA PRIVATE KEY-----');signStr.setPrivateKey(privKey)//用私钥给明文加签,例子中使用SHA1算法,其它算法也可,如:SHA256// var signature = signStr.sign(plainText, CryptoJS.SHA256, "sha256");var signature = signStr.sign(plainText, CryptoJS.SHA1, "sha1"); //和后端使用一样的散列算法return signature;}//验签function RsaVerify(plainText, signature){var verify = new JSEncrypt();//设置公钥// verify.setPublicKey('-----BEGIN PUBLIC KEY-----' + pubKey + '-----END PUBLIC KEY-----');verify.setPublicKey(pubKey)//验证方法有三个参数明文,用私钥加签后的字符串,加签的算法(跟上文保持一致哈~)var verified = verify.verify(plainText, signature, CryptoJS.SHA1);  //和后端使用一样的散列算法return verified;}//签名function RsaSign_jsrsasign(plainText){// 创建 Signature 对象let signature=new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:privKey});    //!这里指定 私钥 pem!signature.updateString(plainText);let a = signature.sign();let sign = hextob64(a);return sign}//验签function RsaVerify_jsrsasign(plainText, signature){// !要重新new 一个Signature, 否则, 取摘要和签名时取得摘要不一样, 导致验签误报失败(原因不明)!let signatureVf = new KJUR.crypto.Signature({alg:"SHA1withRSA",prvkeypem:pubKey});signatureVf.updateString(plainText);// !接受的参数是16进制字符串!let b = signatureVf.verify(b64tohex(signature));return b;}
</script>

二、后端

后端UE4写三个函数,一个是生成公私密钥函数。一个是加签函数,使用私钥加签字符串并将签文发送到前端进行解签。另一个是解签函数,需要接收前端发来的签文,并使用公钥验证签文。
以下为实现逻辑:

1. C++代码

RSALibrary.h

#pragma once#include <string>
using namespace std;#include "../../../ThirdParty/crypto/include/Win64/osrng.h"
#include "../../../ThirdParty/crypto/include/Win64/aes.h"
#include "../../../ThirdParty/crypto/include/Win64/hex.h"
#include "../../../ThirdParty/crypto/include/Win64/files.h"
#include "../../../ThirdParty/crypto/include/Win64/rsa.h"
#include "../../../ThirdParty/crypto/include/Win64/base64.h"using namespace CryptoPP;#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "RSALibrary.generated.h"/*** */
UCLASS()
class H_CRYPTO860_PLUGIN_API URSALibrary : public UBlueprintFunctionLibrary
{GENERATED_BODY()public://生成RSA公钥和私钥UFUNCTION(BlueprintCallable, meta = (DisplayName = "GenerateRSAKey_ue4", Wordkeys = "GenerateRSAKey_ue4"), Category= "RSA")static bool GenerateRSAKey_ue4(int keyLength, FString privFilename, FString pubFilename);//RSA使用私钥签名UFUNCTION(BlueprintCallable, meta = (DisplayName = "RsaSignString", Wordkeys = "RsaSignString"), Category= "RSA")static FString RsaSignString(FString privFilename, FString tobeSignString);//RSA使用公钥验证UFUNCTION(BlueprintCallable, meta = (DisplayName = "RsaVerString", Wordkeys = "RsaVerString"), Category= "RSA")static bool RsaVerString(FString pubFilename, FString tobeSignString, FString signedString);private://随机种子static AutoSeededRandomPool & getRng();
};

RSALibrary.cpp

#include "RSALibrary.h"
#include "assert.h"//生成公私密钥
bool URSALibrary::GenerateRSAKey_ue4(int keyLength, FString privFilename, FString pubFilename)
{bool isGenerate = true;try{RSAES_PKCS1v15_Decryptor priv(getRng(), keyLength);Base64Encoder privFile(new FileSink(TCHAR_TO_ANSI(*privFilename))); //生成base64格式密文priv.AccessMaterial().Save(privFile);privFile.MessageEnd();RSAES_PKCS1v15_Encryptor pub(priv);Base64Encoder pubFile(new FileSink(TCHAR_TO_ANSI(*pubFilename)));   //生成base64格式密文pub.AccessMaterial().Save(pubFile);pubFile.MessageEnd();}catch (CryptoPP::Exception& e) {isGenerate = false;cout << "RSALibrary::GenerateRSAKey_ue4 Error: " << e.what() << endl;}return  isGenerate;
}//签名
FString URSALibrary::RsaSignString(FString privFilename, FString tobeSignString)
{const char* fileName = TCHAR_TO_ANSI(*privFilename);FileSource priFile(fileName, true, new Base64Decoder);    //使用base64格式密钥RSASSA_PKCS1v15_SHA_Signer privkey(priFile);string signedString;  //签名后的文本StringSource(TCHAR_TO_UTF8(*tobeSignString), true, new SignerFilter(getRng(), privkey, new Base64Encoder(new StringSink(signedString))));//使用base64格式密文return UTF8_TO_TCHAR(signedString.c_str());
}//验证签名
bool URSALibrary::RsaVerString(FString pubFilename, FString tobeSignString, FString signedString)
{const char* fileName = TCHAR_TO_ANSI(*pubFilename);   FileSource pubFile(fileName, true, new Base64Decoder);  //使用base64格式密钥RSASSA_PKCS1v15_SHA_Verifier pubkey(pubFile);StringSource signatureString(TCHAR_TO_UTF8(*signedString), true, new Base64Decoder); //使用base64格式密文if (signatureString.MaxRetrievable() != pubkey.SignatureLength()){return false;}SecByteBlock signature(pubkey.SignatureLength());signatureString.Get(signature, signature.size());SignatureVerificationFilter *verifierFilter = new SignatureVerificationFilter(pubkey);verifierFilter->Put(signature, pubkey.SignatureLength());StringSource(TCHAR_TO_UTF8(*tobeSignString), true, verifierFilter);return verifierFilter->GetLastResult();
}//自动生成随机种子
AutoSeededRandomPool & URSALibrary::getRng()
{static AutoSeededRandomPool m_Rng;return m_Rng;
}

2. 蓝图


后端UE4自己实现签名和验签

UE4签名后,将签文发给前端进行验签

UE4接收前端发来的签文,进行验签。

测试结果

将html页面加载到UE4中,运行效果如下:

  1. 后端UE4加签,前端html分别使用JSEncrypt库和jsrsasign库解签

  2. 前端html分别使用JSEncrypt库和jsrsasign库加签,后端UE4解签

         case 'JSEncrypt签名':textStr = RsaSign(content);console.log(textStr);window.ue4("Decoder",{"Type":"RSA_Sign","content":textStr});deStr = RsaVerify(content, textStr);// deStr = RsaVerify_jsrsasign(content, textStr);console.log(deStr);break;case 'jsrsasign签名':textStr = RsaSign_jsrsasign(content);console.log(textStr);window.ue4("Decoder",{"Type":"RSA_Sign","content":textStr});deStr = RsaVerify_jsrsasign(content, textStr);// deStr = RsaVerify(content, textStr);console.log(deStr);break;

前端签名
完美实现前后端加解签。


总结

一般情况下,前端自己实现加解签没有问题,后端自己实现加解签也没有问题。问题主要出在2个方面:

  1. 前后端编码格式不一样
    前端加签的结果传到后端,或者后端加签的结果传到前端,对方无法识别接收到的字符串。主要原因在于双方的字符串编码格式不一样,前端的是base64格式,后端的就不能是hex格式,需要使用同样的编码格式。
  2. 散列算法不一样
    因为后端使用SHA散列算法,这是默认的SHA1算法,所以前端也要使用SHA1算法。
  3. 密钥格式不一样
    后端Crypto++库生成的是key格式的密钥,前端jsrsasign库使用的是pem格式的密钥(JSEncrypt库可以兼容两种格式),所以需要将key格式转换为pem格式,转换请参考:RSA公钥私钥生成pem文件

参考

前端开源项目 CDN 加速服务网站
前端RSA加密、解密、签名、验签。本文包含jsencrypt和jsrsasign两种方法教程
jsrsasign使用笔记(加密,解密,签名,验签)
JavaScript怎么做RSA加密解密, 签名和验签? 有没有好用的库?
RSA PKCS1 填充方式
Crypto++库实现AES和RSA加密解密
基于Crypto++/Cryptopp的rsa密钥生成,rsa加密、解密,rsa签名、验签
Crypto++使用
利用Crypto++实现RSA加密算法

RSA签名解签 - 前端JSEncrypt库、jsrsasign库和后端UE4使用Crypto++互相加解签相关推荐

  1. 微信小程序加签验签(wxapp_rsa,jsencrypt)和egg搭建的后端交互(jsrsasign,node_rsa)最全!!!

    微信小程序加签验签(wxapp_rsa,jsencrypt)和egg搭建的后端交互(jsrsasign,node_rsa)最全!!! RAS加密 ​ RSA加密算法是一种非对称加密算法. ​ 假设 A ...

  2. java支付宝rsa2签名_JAVA RSA签名 解签(利用支付宝封装的函数)

    package com.mlgd.api.util; import com.alibaba.fastjson.JSON; import com.alipay.api.AlipayApiExceptio ...

  3. [crypto]-52-python3中rsa(签名验签加密解密)aes(ecb cbc ctr)hmac的使用,以及unittest测试用

    环境: 在ubuntu14.04下,记得安装:sudo pip3 install pycrypto 代码示例1: =========================== import base64 f ...

  4. 微信小程序-RSA签名、验签、加密、解密

    title: [小程序]RSA签名 type: categories date: 2017-05-27 17:01:15 categories: 小程序 tags: [RSA, 签名] 一个适用于微信 ...

  5. java/php/c#版rsa签名以及java验签实现--转

    在开放平台领域,需要给isv提供sdk,签名是Sdk中需要提供的功能之一.由于isv使用的开发语言不是单一的,因此sdk需要提供多种语言的版本.譬如java.php.c#.另外,在电子商务尤其是支付领 ...

  6. 叙述无保密机制的rsa签名过程_安全系列之——RSA的公钥私钥有多少人能分的清楚?RSA的签名验签与加密解密如何使用公私钥?...

    在对接很多的互联网公司的开发平台时,这些互联网公司未来自身平台的安全,都会需要调用方签名确认调用方的身份是合法的,同时未来信息网络传输的安全可能还需要加密解密.比如对接支付宝.微信开放平台时,需要配置 ...

  7. .NET Core RSA 签名和验签(密钥为 16 进制编码)

    使用 OpenSSL 生成公私钥对,命令: $ openssl genrsa -out rsa_1024_priv.pem$ openssl pkcs8 -topk8 -inform PEM -in ...

  8. RSA签名验签学习笔记

    RSA私钥签名时要基于某个HASH算法,比如MD5或者SHA1等.之前我一直认为签名的过程是:先对明文做HASH计算,然后用私钥直接对HASH值加密.最近才发现不是那么简单,需要对HASH后的数据进行 ...

  9. C++ 使用OpenSSL 基于SHA1摘要的RSA签名及验签 与Java平台互通

    文章目录 准备 C++ Java RSASignature.java RSAEncrypt.java Base64.java 准备 配置OpenSSL环境 配置VS2015环境 生成公私秘钥 然后你们 ...

最新文章

  1. 业界 | 微软亚洲研究院携手培生,以人工智能技术赋能个性化学习
  2. 营销系统--手动补偿
  3. python爬虫原理-python爬虫原理详细讲解
  4. WIN10系统下sqlmap没有颜色和nmap无法使用的问题解决
  5. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (四) —— ContentProvider...
  6. linux下的vconfig配置_Linux系统下安装配置-OpenLDAP-phpLDAPadmin
  7. matlab 拼接矩阵,Matlab 不同行数矩阵拼接
  8. python模块的使用方法_python中requests模块的使用方法
  9. bugku never_give_up file_get_contents()有php://input漏洞 eregi \x00绕过
  10. 在oracle中 缺失关键字,缺失关键字解决方案
  11. 基于数字证书的UKEY安全登录 与身份认证技术研究
  12. 机器学习及其应用2013, 机器学习及其应用2015
  13. 智能急救站入驻公共场所,搭起生命安全新防线
  14. 关于解决缓慢渐变维的3种方式
  15. leakcanary内存泄露检测工具 Dumping memory, app will freeze. Brrr
  16. Python办公自动化Excel
  17. 【 Apifox】Apifox的前置操作与后置操作
  18. 学习《Redis设计与实现》Chapter1
  19. 【Sparse-to-Dense】《Sparse-to-Dense:Depth Prediction from Sparse Depth Samples and a Single Image》
  20. 2023前端面试总结含参考答案

热门文章

  1. shell脚本配置运行python程序,小技巧之 Linux 软连接的使用
  2. abaqus二次开发简单插件
  3. 为什么是base64编码,而不是base32、base16、base63?
  4. Build and run UDK2021.8 Emulator in Deepin-20.2.4
  5. win7系统环境变量path默认值
  6. layui中的ajax
  7. 默克尔树 Merkle Tree
  8. 模拟CMOS集成电路设计入门学习(8)
  9. 系统权限设计 - 基本概念和思路
  10. AutoRunner怎么做脚本参数化实现用例的自动化批量执行