前端页面显示了签名的密钥怎么办(aes加密解密工具类)

2023-03-05 3:33:11 密语知识 思思

1,首先引入前端需要用到的js:crypto-js,下载命令 npm install crypto-js

将 crypto-js 文件放到要引用的路径

以下是要引用到的js

2,引用,jQuery也要记得引用哦

3,在登录页的登录按钮的function里,设置key值和iv值,这是加密的设置字段,定义要进行加密的密码passwordNode

下面再加个function

function aesMinEncrypt(key, iv, word){

var _word = CryptoJS.enc.Utf8.parse(word),

_key = CryptoJS.enc.Utf8.parse(key),

_iv = CryptoJS.enc.Utf8.parse(iv);

var encrypted = CryptoJS.AES.encrypt(_word, _key, {

iv: _iv,

mode: CryptoJS.mode.CBC,

padding: CryptoJS.pad.Pkcs7

});

return encrypted.toString();

}

3,(另一种)上面的过程也可以这样

function encryption(){

//密钥 (需要前端和后端保持一致)十六位作为密钥

var key = "ABCDEFGHIJKL_key";

//密钥偏移量 (需要前端和后端保持一致)十六位作为密钥偏移量

var iv = "ABCDEFGHIJKLM_iv";

var username=document.getElementById("usr").value;

// var passwordNode=document.getElementById("paw").value;

var passwordNode=aesMinEncrypt(key,iv,$("#paw").val());

console.log(passwordNode);

alert("加密后的密码为:"+passwordNode);

$.ajax({

url: "login",

async:false,

type: "POST",

data: {'username':username,'password':passwordNode},

success: function (result) {

$("html").html(result);

}

});

}

function aesMinEncrypt(key, iv, word){

var _word = CryptoJS.enc.Utf8.parse(word),

_key = CryptoJS.enc.Utf8.parse(key),

_iv = CryptoJS.enc.Utf8.parse(iv);

var encrypted = CryptoJS.AES.encrypt(_word, _key, {

iv: _iv,

mode: CryptoJS.mode.CBC,

padding: CryptoJS.pad.Pkcs7

});

return encrypted.toString();

$("#form").submit();

}

4,前端加密就算是完成了,接下来是后端解密,后端解密需要用到一个工具类 AESUtils,里面是解密方法代码如下

package com.wuye.common.utils;

import cn.jpush.api.utils.StringUtils;

import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

/**

* TODO

*

* @author CSD

* @date 2022-07-28 14:16

*/

public class AESUtils {

//密钥 (需要前端和后端保持一致)十六位作为密钥

private static final String KEY = "ABCDEFGHIJKL_key";

//密钥偏移量 (需要前端和后端保持一致)十六位作为密钥偏移量

private static final String IV = "ABCDEFGHIJKLM_iv";

//算法

private static final String ALGORITHMSTR = "AES/CBC/PKCS5Padding";

/**

* base 64 decode

* @param base64Code 待解码的base 64 code

* @return 解码后的byte[]

* @throws Exception

*/

public static byte[] base64Decode(String base64Code) throws Exception{

return StringUtils.isEmpty(base64Code) ? null : new BASE64Decoder().decodeBuffer(base64Code);

}

/**

* AES解密

* @param encryptBytes 待解密的byte[]

* @return 解密后的String

* @throws Exception

*/

public static String aesDecryptByBytes(byte[] encryptBytes) throws Exception {

Cipher cipher = Cipher.getInstance(ALGORITHMSTR);

byte[] temp = IV.getBytes("UTF-8");

IvParameterSpec iv = new IvParameterSpec(temp);

cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY.getBytes(), "AES"), iv);

byte[] decryptBytes = cipher.doFinal(encryptBytes);

System.out.print(new String(decryptBytes));

return new String(decryptBytes);

}

/**

* 将base 64 code AES解密

* @param encryptStr 待解密的base 64 code

* @return 解密后的string

* @throws Exception

*/

public static String aesDecrypt(String encryptStr) throws Exception {

return StringUtils.isEmpty(encryptStr) ? null : aesDecryptByBytes(base64Decode(encryptStr));

}

//测试一下

public static void main(String[] args) throws Exception {

String str = "Q uus tQvLdwtGSldhrtKQ==";

str = str.replace(" ", "+");

System.out.println(str);

aesDecrypt(str);

}

}

5,在密码验证的java页面做解密,建议打断点看看走的哪里,解密很简单,就一句

password = AESUtils.aesDecrypt(getPassword

如何使用CryptoJS的AES方法进行加密和解密

首先准备一份明文和秘钥:

var plaintText = 'aaaaaaaaaaaaaaaa'; // 明文

var keyStr = 'bbbbbbbbbbbbbbbb'; // 一般key为一个字符串

参看官网文档,AES方法是支持AES-128、AES-192和AES-256的,加密过程中使用哪种加密方式取决于传入key的类型,否则就会按照AES-256的方式加密。

CryptoJS supports AES-128, AES-192, and AES-256. It will pick the variant by the size of the key you pass in. If you use a passphrase, then it will generate a 256-bit key.

由于Java就是按照128bit给的,但是由于是一个字符串,需要先在前端将其转为128bit的才行。

最开始以为使用CryptoJS.enc.Hex.parse就可以正确地将其转为128bit的key。但是不然...

经过多次尝试,需要使用CryptoJS.enc.Utf8.parse方法才可以将key转为128bit的。好吧,既然说了是多次尝试,那么就不知道原因了,后期再对其进行更深入的研究。

// 字符串类型的key用之前需要用uft8先parse一下才能用

var key = CryptoJS.enc.Utf8.parse(keyStr);

由于后端使用的是PKCS5Padding,但是在使用CryptoJS的时候发现根本没有这个偏移,查询后发现PKCS5Padding和PKCS7Padding是一样的东东,使用时默认就是按照PKCS7Padding进行偏移的。

// 加密

var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

});

由于CryptoJS生成的密文是一个对象,如果直接将其转为字符串是一个Base64编码过的,在encryptedData.ciphertext上的属性转为字符串才是后端需要的格式。

var encryptedBase64Str = encryptedData.toString();

// 输出:'RJcecVhTqCHHnlibzTypzuDvG8kjWC+ot8JuxWVdLgY=

console.log(encryptedBase64Str);

// 需要读取encryptedData上的ciphertext.toString()才能拿到跟Java一样的密文

var encryptedStr = encryptedData.ciphertext.toString();

// 输出:'44971e715853a821c79e589bcd3ca9cee0ef1bc923582fa8b7c26ec5655d2e06

console.log(encryptedStr);

由于加密后的密文为128位的字符串,那么解密时,需要将其转为Base64编码的格式。

那么就需要先使用方法CryptoJS.enc.Hex.parse转为十六进制,再使用CryptoJS.enc.Base64.stringify将其变为Base64编码的字符串,此时才可以传入CryptoJS.AES.decrypt方法中对其进行解密。

// 拿到字符串类型的密文需要先将其用Hex方法parse一下

var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedStr);

// 将密文转为Base64的字符串

// 只有Base64类型的字符串密文才能对其进行解密

var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);

使用转为Base64编码后的字符串即可传入CryptoJS.AES.decrypt方法中进行解密操作。

// 解密

var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, {

mode: CryptoJS.mode.ECB,

padding: CryptoJS.pad.Pkcs7

});

经过CryptoJS解密后,依然是一个对象,将其变成明文就需要按照Utf8格式转为字符串。

// 解密后,需要按照Utf8的方式将明文转位字符串

var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8);

console.log(decryptedStr); // 'aaaaaaaaaaaaaaaa'

Flutter AES/RAS 加解密工具类

因项目需要用到加解密,然后研究了下flutter大部分是用原生实现加解密的,但是这样不是我想要的,后面找资料发现dart有一个加密工具 encrypt 。然后研究了下,可以实现我们大部分加解密。

使用Dart实现加解密,有对称加密AES,非对称加密RSA。

工具类封装了AES加解密,RSA加解密和数字签名,RSA也实现分段加解密。

一、导包

二、工具类

怎么测试给数据库加密的android模块

1.概述

SharedPreferences是Android提供用来存储一些简单配置信息的机制,其以KEY-VALUE对的方式进行存储,以便我们可以方便进行读取和存储。主要可以用来存储应用程序的欢迎语、常量参数或登录账号密码等。

2.实例

(1)创建项目SharedPreferencesDemo项目

(2)编辑主界面的布局文件main.xml如下:

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="SharedPreferences,是Android提供用来存储一些简单的配置信息的一种机制。"

/

(3)创建AES加解密工具类AESEncryptor.java

其中主要提供加密encrypt、解密decrypt两个方法。(AES加解密算法具体大家可以到网上搜索相关资料)

以下为该类文件的源码:

package ni.demo.sharedpreferences;

import java.security.SecureRandom;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.SecretKey;

import javax.crypto.spec.SecretKeySpec;

/**

* AES加密器

* @author Eric_Ni

*

*/

public class AESEncryptor {

/**

* AES加密

*/

public static String encrypt(String seed, String cleartext) throws

Exception {

byte[] rawKey = getRawKey(seed.getBytes());

byte[] result = encrypt(rawKey, cleartext.getBytes());

return toHex(result);

}

/**

* AES解密

*/

public static String decrypt(String seed, String encrypted) throws

Exception {

byte[] rawKey = getRawKey(seed.getBytes());

byte[] enc = toByte(encrypted);

byte[] result = decrypt(rawKey, enc);

return new String(result);

}

private static byte[] getRawKey(byte[] seed) throws Exception {

KeyGenerator kgen = KeyGenerator.getInstance("AES");

SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

sr.setSeed(seed);

kgen.init(128, sr); // 192 and 256 bits may not be available

SecretKey skey = kgen.generateKey();

byte[] raw = skey.getEncoded();

return raw;

}

private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception

{

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

Cipher cipher = Cipher.getInstance("AES");

cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

byte[] encrypted = cipher.doFinal(clear);

return encrypted;

}

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws

Exception {

SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

Cipher cipher = Cipher.getInstance("AES");

cipher.init(Cipher.DECRYPT_MODE, skeySpec);

byte[] decrypted = cipher.doFinal(encrypted);

return decrypted;

}

public static String toHex(String txt) {

return toHex(txt.getBytes());

}

public static String fromHex(String hex) {

return new String(toByte(hex));

}

public static byte[] toByte(String hexString) {

int len = hexString.length()/2;

byte[] result = new byte[len];

for (int i = 0; i len; i++)

result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2),

16).byteValue();

return result;

}

public static String toHex(byte[] buf) {

if (buf == null)

return "";

StringBuffer result = new StringBuffer(2*buf.length);

for (int i = 0; i buf.length; i++) {

appendHex(result, buf[i]);

}

return result.toString();

}

private final static String HEX = "0123456789ABCDEF";

private static void appendHex(StringBuffer sb, byte b) {

sb.append(HEX.charAt((b4)0x0f)).append(HEX.charAt(b0x0f));

}

}

(4)编辑SharedPreferencesDemo.java

源码如下:

package ni.demo.sharedpreferences;

import android.app.Activity;

import android.content.SharedPreferences;

import android.content.SharedPreferences.Editor;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class SharedPreferencesDemo extends Activity {

public static final String MY_PREFERENCES = "MY_PREFERENCES";

//Preferences文件的名称

public static final String MY_ACCOUNT = "MY_ACCOUNT"; //

public static final String MY_PASSWORD = "MY_PASSWORD";

private EditText edtAccount;

private EditText edtPassword;

private Button btnClear;

private Button btnExit;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

edtAccount = (EditText)findViewById(R.id.edtAccount);

edtPassword = (EditText)findViewById(R.id.edtPassword);

//获取名字为“MY_PREFERENCES”的参数文件对象,并获得MYACCOUNT、MY_PASSWORD元素的值。

SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);

String account = sp.getString(MY_ACCOUNT, "");

String password = sp.getString(MY_PASSWORD, "");

//对密码进行AES解密

try{

password = AESEncryptor.decrypt("41227677", password);

}catch(Exception ex){

Toast.makeText(this, "获取密码时产生解密错误!", Toast.LENGTH_SHORT);

password = "";

}

//将账号和密码显示在EditText控件上。

edtAccount.setText(account);

edtPassword.setText(password);

//获取"清空"按钮的对象,并为其绑定监听器,如被点击则清空账号和密码控件的值。

btnClear = (Button)findViewById(R.id.btnClear);

btnClear.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View arg0) {

edtAccount.setText("");

edtPassword.setText("");

}

});

//获取“退出”按钮的对象,并为其绑定监听,如被点击则退出程序。

btnExit = (Button)findViewById(R.id.btnExit);

btnExit.setOnClickListener(new OnClickListener(){

@Override

public void onClick(View arg0) {

SharedPreferencesDemo.this.finish();

}

});

}

@Override

protected void onStop() {

super.onStop();

//获得账号、密码控件的值,并使用AES加密算法给密码加密。

String account = edtAccount.getText().toString();

String password = edtPassword.getText().toString();

try{

password = AESEncryptor.encrypt("41227677", password);

}catch(Exception ex){

Toast.makeText(this, "给密码加密时产生错误!", Toast.LENGTH_SHORT);

password = "";

}

//获取名字为“MY_PREFERENCES”的参数文件对象。

SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);

//使用Editor接口修改SharedPreferences中的值并提交。

Editor editor = sp.edit();

editor.putString(MY_ACCOUNT, account);

editor.putString(MY_PASSWORD,password);

editor.commit();

}

}

(5)效果测试

首先,在AVD我们可以看到如下界面,在两个控件上我们分别输入abc和123456。

接着,我们打开DDMS的File

Explore可以看到在data-data-ni-shared_prefs下面产生了一个名字叫做MY_PREFERENCES.xml的文件,该文件就是用来存储我们刚才设置的账号和密码。

将其导出,并打开,可以看到如下内容:

abc

04B75FAD36E907BE50CE3222B0052B79

这说明我们可以成功将账号和加密后的密码保存下来了。

最后,我们点击“退出”按钮将应用程序结束掉,再重新打开。我们又再次看到我们退出前的界面,账号密码已经被重新读取出来。

文章的最后,我们进入Android API手册,看看关于SharedPreferences的介绍:

Interface for accessing and modifying preference data returned by

getSharedPreferences(String, int). For any particular set of preferences, there

is a single instance of this class that all clients share. Modifications to the

preferences must go through an SharedPreferences.Editor object to ensure the

preference values remain in a consistent state and control when they are

committed to storage.

SharedPreferences是一个用来访问和修改选项数据的接口,通过getSharedPreferences(Stirng,int)来获得该接口。对于任何特别的选项集,只能有一个实例供所有客户端共享。针对选项参数的修改必须通过一个SharedPreferences.Editor对象来进行,以保证所有的选项值保持在一个始终如一的状态,并且通过该对象提交存储。

可见,SharedPreferences操作选项文件时是线程安全的。