uni-app app vue 小程序 RSA 加密/解密 使用 jsencrypt 踩坑(字符乱码问题)(二)
<p>真是图样图样森破呀,接上篇:《uni-app app vue 小程序 RSA 加密/解密 使用 jsencrypt 踩坑(Message too long for RSA/Cannot read property 'appName')(一)》,</p><p>本以为后端RSA加密,前端进行解密这个风波是过去了,结果今天又发现了异常:</p>
<p><img src="https://img2020.cnblogs.com/blog/983493/202106/983493-20210625165836398-193761201.png"></p>
<p>这是一段长数据解密后的json。</p>
<p>然而在格式化的时候,发现该json字符串里居然有乱码,导致格式不正确了,那就更别提转化为json对象了。</p>
<p> </p>
<p>…………</p>
<p>…………</p>
<p>反正折腾了很久,发现每次遇到很长的数据密文,解密后就会有这种情况。也真是难为RSA算法了,居然要帮我算这么长的解密。</p>
<p> </p>
<p>快下班了,直接上解决方案吧:</p>
<p>第一步:后端Java进行分段加密。举个栗子:</p>
<p> 【以前的加密方式】:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> String content = "1234567890"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">2</span>
<span style="color: rgba(0, 128, 128, 1)">3</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] data =<span style="color: rgba(0, 0, 0, 1)"> content.getBytes();
</span><span style="color: rgba(0, 128, 128, 1)">4</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] encodedData =<span style="color: rgba(0, 0, 0, 1)"> RSAUtil.encrypt(data, publicKey);
</span><span style="color: rgba(0, 128, 128, 1)">5</span>
<span style="color: rgba(0, 128, 128, 1)">6</span> String encryptedContent = Base64Util.encode(encodedData);</pre>
</div>
<p> 这种是将所有json字符串加密为一个字符串。密文有的时候很长很长,几十甚至上百KB。</p>
<p> </p>
<p> 【优化后的加密方式】:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> String content = "1234567890"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>
<span style="color: rgba(0, 128, 128, 1)"> 3</span> List<String> encryptedList = <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">每X个字符,加密一次</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (content != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">int</span> startIndex = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> <span style="color: rgba(0, 0, 255, 1)">int</span> endIndex = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 255, 1)">int</span> subLength = 50<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">10</span>
<span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)">12</span> endIndex = startIndex +<span style="color: rgba(0, 0, 0, 1)"> subLength;
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (content.length() <=<span style="color: rgba(0, 0, 0, 1)"> endIndex) {
</span><span style="color: rgba(0, 128, 128, 1)">15</span> endIndex = startIndex + (content.length() -<span style="color: rgba(0, 0, 0, 1)"> startIndex);
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">17</span>
<span style="color: rgba(0, 128, 128, 1)">18</span>
<span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">region 将截取到的字符串,进行加密</span>
<span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] data =<span style="color: rgba(0, 0, 0, 1)"> content.substring(startIndex, endIndex).getBytes();
</span><span style="color: rgba(0, 128, 128, 1)">21</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] encodedData =<span style="color: rgba(0, 0, 0, 1)"> RSAUtil.encrypt(data, publicKey);
</span><span style="color: rgba(0, 128, 128, 1)">22</span> String encryptedStr =<span style="color: rgba(0, 0, 0, 1)"> Base64Util.encode(encodedData);
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)"> encryptedList.add(encryptedStr);
</span><span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">endregion</span>
<span style="color: rgba(0, 128, 128, 1)">26</span>
<span style="color: rgba(0, 128, 128, 1)">27</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> startIndex +=<span style="color: rgba(0, 0, 0, 1)"> subLength;
</span><span style="color: rgba(0, 128, 128, 1)">29</span>
<span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (startIndex >=<span style="color: rgba(0, 0, 0, 1)"> content.length()) {
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)">32</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">33</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">34</span> }</pre>
</div>
<p> 这样返回的就是一个string数组到前台,格式如:{ data: ["密文片段1", "密文片段2", "密文片段3"] } </p>
<p> </p>
<p>第二步:前端解密&拼接:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> const decryptor = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> JSEncrypt();
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> const privateKey = "privateKey"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">decryptor.setPrivateKey(privateKey);
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>
<span style="color: rgba(0, 128, 128, 1)"> 5</span> let jsonStr = ""<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 255, 1)">if</span> (encryptedList && encryptedList.length > 0<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> (let encrypted of encryptedList) {
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span> jsonStr +=<span style="color: rgba(0, 0, 0, 1)"> decryptor.decryptLong(encrypted);
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 128, 128, 1)">10</span> }</pre>
</div>
<p> 这样将每个密文片段,解密后,再按顺序拼接起来,即可得到加密前的原始json字符串。随后直接转化为json对象即可:</p>
<p><img src="https://img2020.cnblogs.com/blog/983493/202106/983493-20210625172529674-274837067.png"></p>
<p> </p>
<p> </p>
<p>搞定,收工,回家吃饭!</p>
<p> </p>
<p>如果对您有帮助,方便的话请点个赞吧,谢谢~</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/wshisboy/p/14931895.html
頁:
[1]