Unity SKFramework框架(二十五)、RSA算法加密、签名工具 RSA Crypto

举报
CoderZ1010 发表于 2022/09/25 04:50:56 2022/09/25
【摘要】 目录 简介 函数 1.pem公钥内容转xml 2.pem私钥内容转xml  3.使用公钥对数据进行加密 4.使用私匙对待签名内容进行签名 示例 简介 在调用Java后端接口,需要使用后端提供的pem私钥,在Unity中使用RSA算法对参数进行签名时,需要先将pem文件中的私钥内容转换为c#支持的xm...

目录

简介

函数

1.pem公钥内容转xml

2.pem私钥内容转xml 

3.使用公钥对数据进行加密

4.使用私匙对待签名内容进行签名

示例


简介

在调用Java后端接口,需要使用后端提供的pem私钥,在Unity中使用RSA算法对参数进行签名时,需要先将pem文件中的私钥内容转换为c#支持的xml格式再进行签名,该工具提供了转换及签名的函数,已上传至我的开发框架SKFramework中的开发工具包中,如图所示:

依赖第三方库:BouncyCastle.Crypto.dll

SKFramework开源地址:

https://github.com/136512892/SKFramework

函数

1.pem公钥内容转xml


  
  1. /// <summary>
  2. /// pem公钥内容转xml
  3. /// </summary>
  4. /// <param name="publicKey"></param>
  5. /// <returns></returns>
  6. public static string Convert2XMLPublicKey(string pem)
  7. {
  8. RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(pem));
  9. string XML = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
  10. Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
  11. Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
  12. return XML;
  13. }

2.pem私钥内容转xml 


  
  1. /// <summary>
  2. /// pem私钥内容转xml
  3. /// </summary>
  4. /// <param name="pem">pem私钥内容</param>
  5. /// <returns></returns>
  6. public static string Convert2XMLPrivateKey(string pem)
  7. {
  8. RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(pem));
  9. return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
  10. Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
  11. Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
  12. Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
  13. Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
  14. Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
  15. Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
  16. Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
  17. Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
  18. }

3.使用公钥对数据进行加密


  
  1. /// <summary>
  2. /// RSA使用公钥对数据加密
  3. /// </summary>
  4. /// <param name="content">待加密内容</param>
  5. /// <param name="publicKeyXml">公钥</param>
  6. /// <returns></returns>
  7. public static string EncryptWithPublicKey(string content, string publicKeyXml)
  8. {
  9. RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  10. byte[] cipherbytes;
  11. rsa.FromXmlString(publicKeyXml);
  12. cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);
  13. return Convert.ToBase64String(cipherbytes);
  14. }

4.使用私匙对待签名内容进行签名


  
  1. /// <summary>
  2. /// RSA使用私匙对签名内容加签名
  3. /// </summary>
  4. /// <param name="sign">代签名内容</param>
  5. /// <param name="privateKeyXml">私钥</param>
  6. /// <param name="hashAlgorithm">哈希算法 默认为SHA256</param>
  7. /// <returns></returns>
  8. public static byte[] SignWithPrivateKey(string sign, string privateKeyXml, string hashAlgorithm = "SHA256")
  9. {
  10. RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
  11. rsa.FromXmlString(privateKeyXml);
  12. byte[] dataBytes = Encoding.UTF8.GetBytes(sign);
  13. byte[] hashbyteSignature = rsa.SignData(dataBytes, hashAlgorithm);
  14. return hashbyteSignature;
  15. }

示例

要求:

将pem文件中的私钥内容Copy下来,需要去除首行和尾行的内容,即“-----BEGIN PRIVATE KEY-----”和“-----END PRIVATE KEY-----”:


  
  1. using System;
  2. using System.Text;
  3. using System.Collections;
  4. using System.Security.Cryptography;
  5. using System.Runtime.InteropServices;
  6. using BestHTTP.WebSocket;
  7. using BestHTTP.SecureProtocol.Org.BouncyCastle.Security;
  8. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  9. using UnityEngine;
  10. using Newtonsoft.Json;
  11. using SK.Framework.Crypto;
  12. /// <summary>
  13. /// 灵犀云会议字幕流接口Demo
  14. /// </summary>
  15. public class SubtitleExample : MonoBehaviour
  16. {
  17. //ws
  18. private WebSocket webSocket;
  19. //地址
  20. [SerializeField] private string host;
  21. //业务码ID 由字幕系统提供
  22. [SerializeField] private string buCode;
  23. //秘钥 与buCode同时提供
  24. [SerializeField] private string secret;
  25. //固定值 目前为1.0
  26. [SerializeField] private string signVersion = "1.0";
  27. //约定的appid 校验用
  28. [SerializeField] private string appid;
  29. //私钥 用于根据RSA签名算法得到签名字符串
  30. [SerializeField, TextArea]
  31. private string privateKey;
  32. //会话ID
  33. private string sid;
  34. #region >> WebSocket回调
  35. //ws建立连接回调
  36. private void OnOpen(WebSocket ws)
  37. {
  38. Debug.Log("WebSocket Open.");
  39. }
  40. //ws接收数据回调
  41. private void OnMessageReceived(WebSocket ws, string message)
  42. {
  43. Debug.Log(string.Format("WebSocket Received: {0}.", message));
  44. }
  45. //ws关闭连接回调
  46. private void OnClosed(WebSocket ws, UInt16 code, string message)
  47. {
  48. Debug.Log(string.Format("WebSocket Closed. Code:{0} Message:{1}.", code, message));
  49. webSocket = null;
  50. }
  51. //ws发生错误回调
  52. private void OnError(WebSocket ws, string error)
  53. {
  54. Debug.LogError(string.Format("WebSocket Error: {0}.", error));
  55. }
  56. #endregion
  57. //十六进制
  58. private string ByteToHex(byte[] data)
  59. {
  60. string hs = string.Empty;
  61. for (int i = 0; i < data.Length; i++)
  62. {
  63. string temp = Convert.ToString(data[i], 16);
  64. hs = temp.Length == 1 ? (hs + "0" + temp) : (hs + temp);
  65. }
  66. return hs.ToUpper();
  67. }
  68. private void OnGUI()
  69. {
  70. GUI.enabled = webSocket == null;
  71. if (GUILayout.Button("Open", GUILayout.Width(200f), GUILayout.Height(50f)))
  72. {
  73. //请求url
  74. string url = string.Format("{0}/subtitle/ws/connect", host);
  75. //时间戳
  76. TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0);
  77. long timestamp = Convert.ToInt64(ts.TotalMilliseconds);
  78. //Int32随机数
  79. string signNonce = UnityEngine.Random.Range(Int32.MinValue, Int32.MaxValue).ToString();
  80. //待签名内容
  81. string signContent = string.Format("buCode={0}&secret={1}&timestamp={2}&signNonce={3}&signVersion={4}&appid={5}",
  82. buCode, secret, timestamp, signNonce, signVersion, appid);
  83. Debug.Log(string.Format("待签名内容:{0}", signContent));
  84. //签名
  85. string sign = ByteToHex(RSACrypto.SignWithPrivateKey(signContent, RSACrypto.Convert2XMLPrivateKey(privateKey)));
  86. Debug.Log(string.Format("签名: {0}", sign));
  87. //最终请求地址
  88. string address = string.Format("{0}?lang={1}&codec={2}&appid={3}&extend={4}&buCode={5}&timestamp={6}&signNonce={7}&signVersion={8}&sign={9}&appid={10}",
  89. url, "cn", "speex", appid, "", buCode, timestamp, signNonce, signVersion, sign, appid);
  90. Debug.Log(string.Format("Uri: {0}", address));
  91. webSocket = new WebSocket(new Uri(address));
  92. webSocket.OnOpen += OnOpen;
  93. webSocket.OnMessage += OnMessageReceived;
  94. webSocket.OnClosed += OnClosed;
  95. webSocket.OnError += OnError;
  96. webSocket.Open();
  97. }
  98. }
  99. }

文章来源: coderz.blog.csdn.net,作者:CoderZ1010,版权归原作者所有,如需转载,请联系作者。

原文链接:coderz.blog.csdn.net/article/details/125874937

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。