sm4 前后端 加密_基于RSA的前后端登陆密码加密JAVA实现(转)

RSA加密算法简介

SA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

RSA加密的java实现

实现的思路,由RSA随机生成一对公钥和私钥,公钥方到客户端,私钥放到服务端,发送数据的时候由公钥对传输数据进行加密,然后发送给服务端,服务端用私钥才能对数据进行解密.下面是代码实现的例子

importjava.nio.charset.StandardCharsets;importjava.security.InvalidKeyException;importjava.security.KeyFactory;importjava.security.KeyPair;importjava.security.KeyPairGenerator;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.interfaces.RSAPrivateKey;importjava.security.interfaces.RSAPublicKey;importjava.security.spec.InvalidKeySpecException;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;importjava.util.HashMap;importjava.util.Map;importjavax.crypto.BadPaddingException;importjavax.crypto.Cipher;importjavax.crypto.IllegalBlockSizeException;importjavax.crypto.NoSuchPaddingException;importorg.apache.commons.codec.binary.Base64;public classMyRSAencryptionMethod {private static Map keyMap = new HashMap<>(); //用于封装随机产生的公钥与私钥

public static voidmain(String[] args) {//生成公钥和私钥

genKeyPair();//加密字符串

String message = "df723820";

System.out.println("随机生成的公钥为:" + keyMap.get(0));

System.out.println("随机生成的私钥为:" + keyMap.get(1));

String messageEn= encrypt(message, keyMap.get(0));

System.out.println("加密后的字符串为:" +messageEn);

String messageDe= decrypt(messageEn, keyMap.get(1));

System.out.println("还原后的字符串为:" +messageDe);

}//随机生成密钥对

public static voidgenKeyPair() {//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象

KeyPairGenerator keyPairGen = null;try{

keyPairGen= KeyPairGenerator.getInstance("RSA");

}catch(NoSuchAlgorithmException e) {

e.printStackTrace();

}//初始化密钥对生成器,密钥大小为96-1024位

assert keyPairGen != null;

keyPairGen.initialize(1024, newSecureRandom());//生成一个密钥对,保存在keyPair中

KeyPair keyPair =keyPairGen.generateKeyPair();

RSAPrivateKey privateKey= (RSAPrivateKey) keyPair.getPrivate(); //得到私钥

RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); //得到公钥

String publicKeyString = newString(Base64.encodeBase64(publicKey.getEncoded()));//得到私钥字符串

String privateKeyString = newString(Base64.encodeBase64((privateKey.getEncoded())));//将公钥和私钥保存到Map

keyMap.put(0, publicKeyString); //0表示公钥

keyMap.put(1, privateKeyString); //1表示私钥

}/**RSA公钥加密

*@paramstr 加密字符串

*@parampublicKey 公钥

*@return密文*/

public staticString encrypt(String str, String publicKey) {//base64编码的公钥

byte[] decoded =Base64.decodeBase64(publicKey);

RSAPublicKey pubKey= null;

String outStr= null;try{

pubKey= (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(newX509EncodedKeySpec(decoded));

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

cipher.init(Cipher.ENCRYPT_MODE, pubKey);

outStr=Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));

}catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException |NoSuchAlgorithmException e) {

e.printStackTrace();

}//RSA加密

returnoutStr;

}/**RSA私钥解密

*@paramstr 加密字符串

*@paramprivateKey 私钥

*@return铭文*/

public staticString decrypt(String str, String privateKey) {//64位解码加密后的字符串

byte[] inputByte =Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));//base64编码的私钥

byte[] decoded =Base64.decodeBase64(privateKey);

RSAPrivateKey priKey= null;//RSA解密

Cipher cipher = null;

String outStr= null;try{

priKey= (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(newPKCS8EncodedKeySpec(decoded));

cipher= Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, priKey);

outStr= newString(cipher.doFinal(inputByte));

}catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException |InvalidKeyException e) {

e.printStackTrace();

}returnoutStr;

}

}

运行结果:

随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCi+2HgEYFX+8XgpNGK49hwufR3fWkD6vs8gll0qYsnF2RmjiL94w+UOP8IGjapzliZ1w8CFvJ5aO/U5ALG7AzlboZC8xl3n8nmCsVfGNtXQlo2PJVCNziP+6hFar5Jyo7t98Eg9MLQ/VY+qIKmUfd/AXnA12Teik+zGmQeeeGagwIDAQAB

随机生成的私钥为:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKL7YeARgVf7xeCk0Yrj2HC59Hd9aQPq+zyCWXSpiycXZGaOIv3jD5Q4/wgaNqnOWJnXDwIW8nlo79TkAsbsDOVuhkLzGXefyeYKxV8Y21dCWjY8lUI3OI/7qEVqvknKju33wSD0wtD9Vj6ogqZR938BecDXZN6KT7MaZB554ZqDAgMBAAECgYBdY7A8xasY8FL9m1Pawx410cgsY/c14ILftE1wFOqAlt3YCiAw3NgDdflk+ihSesO4O0wFRYLhYOj0U0boF0B3lOLwefLndglMG1f0dM8lehHiaaDnl8kk5rdRjk3Xc2MCpglM7/Z5Tir9zuuaqS0Ps+cxop8Ebe92D1L4JPybOQJBAPbnGQleStYyrmAPcj6J1hhYCWm3V4H8csepAiMNAfsYwLN21Z8j7muiYTtHyTRTuXVn7KaJ1OKCT3qu5YkpcVUCQQCo/LReIR7xRjdsgvnf/G0Q5h6lyJ5w7FKmS/rWiKxRtGcG826MqJc1lP9iBtiHh9RY39s6LwXwxcZJySw01jx3AkEAs4fa9qrvs8zqasMQiVTkrpLlVU+Re907AN9txFrjA9g91sEkGDGiXfWWyeoq7berdSl6NKaoe4PRkx21ngTaeQJBAJdD3ZCExVXkLKiNdW7yXg7KbpSnyGv8nt8NFDQFk3pvqemm7kYqg3ALN69fwWNQStxjRbIHdaHY524VDeUeAHECQAzE19Ktuiq9xdBngwuojWnoYgKo59mJbqhJiykIdcrYsClcyyF0DMK36thg+KvCRzMLDYBjiyXsbVUXXZj0BRc=

加密后的字符串为:TtFXKWl6Kb3O8TcA0UmosQQcBdIFRdctViqh7OVtY/vX7j4ry2O0Ess+AxEYism4qHEnjPNsqqWTjWGpywDuR2VW+xpni7qLrDR4wmJea9Mp4952R1aLdzeHJy940jCBlXs9zzQHX2ymcmziN2//B2tr3VmHdaBjsX827IezMy8=

还原后的字符串为:df723820

再次运行一次结果:

随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpah3f/oGknklFOCExGJXOXkmj5AwW9Hs6ABDR7DoGXPH08MmYYPZL7eD+baTavOb5/t3JJFswWqq/Uf2j9lCrZYaxDkwOmW/PuSkPxaKaxAnRlbdg6EFlh3j+gn1kxB+74cRQBplb1nqSVgCYSuqaSx8KlMAxv6X4XBKNcmlZHQIDAQAB

随机生成的私钥为:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKlqHd/+gaSeSUU4ITEYlc5eSaPkDBb0ezoAENHsOgZc8fTwyZhg9kvt4P5tpNq85vn+3ckkWzBaqr9R/aP2UKtlhrEOTA6Zb8+5KQ/FoprECdGVt2DoQWWHeP6CfWTEH7vhxFAGmVvWepJWAJhK6ppLHwqUwDG/pfhcEo1yaVkdAgMBAAECgYBHczHWXohe3UMZpmqZQj0sJCf6rxtKMyIlfBGb930hYeHJ5COh2IMH0vOpWqTEfBcOKKdxRZwP8K1Cs1m95QxwDTpKGQ13pwvmLT0iv8Zo+OliRUpriPt+UE+zdO/wIJ3cpJr47nxSsYn4L5RqoJsWqpdJpj/MeB90QdyNM3muAQJBANjoIZ9bUlFJERzYVp0f0ZwBt16u30Ro4Fi6QniWp8Do6/xN0Fab0nuQI/GqRI8ZHdYlTpCgMMNtixz8kRTITbECQQDH8r0xhOuDUh29G+SuUQ+NqzszIwZjPlWBAmxE2ZOWiNx4P+nHWxu2rUlUcCp9c3c3t60SVoNR6Z9lm6msxgEtAkAitkNrNTofOAo9C4IQ8x6gUMX/qQyh7ga5LFWm5rVB8gSSBAHrWlR84bxe2FjQbbyQoLfJ/VjQbZ9trB2rrcKBAkBSgMS0RCZxv1ZqC7JmgygpyrfYt+EQ3k2lt/w4xJZzjPF75NNv4RYkYIhbgRTnQte0c+PEJ1J0YDPXV03B7snZAkEAsoeJzIlIfDLcbG9uVOdxgeyuyww3g72YA8/aOWBiTGZ625Ue5dzvbCI91bpXeBI1q2/aG1XeKasBVhU9+3J+fA==

加密后的字符串为:Am11mhbFpvhHzmq+jcyud7qP2suyDE6iAWpSBnWnE6kdQwvWFy6/ujbMqq6UdOpSf+9I4T8DGGTsFbCjc2Cbv1TDfe+S+IoWRBS4qz9EOc0+116+0yzrPpoIi5bxHcxLgSGfY21kXQHMwSK2TG4jQwPaT5/7CXBB++s2TRt1LSE=

还原后的字符串为:df723820

可以看出公钥每次都是一样。

RSA加密的前端用法

前端用crypto-js进行加密,

npm i jsencrypt,

然后页面头引入import JSEncrypt from 'jsencrypt';

const encrypt = new JSEncrypt();

encrypt.setPublicKey('你的公钥');

password = encrypt.encrypt(‘你的密码’);// 加密后的字符串

后续

在实际应用中RSA加密也还是远远不够,一般还会加入MD5加密的方式,以及加密验证,token等等方式作为请求连接的校验,比如后端加密一个MD5字符串,给前端之后,前端用特定组合加上传输数据返回一个RSA加密的字符串,后端接收后解密,然后和自身的字符串进行对比,以确认数据来源的准确性.

出处链接:https://www.jianshu.com/p/d1e303b976aa

你可能感兴趣的:(sm4,前后端,加密)