如何实现用javascript实现rsa加解密

JavaScript07

如何实现用javascript实现rsa加解密,第1张

用javascript实现rsa加解密的实现方式是通过PKCS完成的。

1、整个定义的function

function pkcs1pad2(s,n) {

if(n <s.length + 11) { // TODO: fix for utf-8

alert("Message too long for RSA")

return null

}

var ba = new Array()

var i = s.length - 1

while(i >= 0 &&n >0) {

var c = s.charCodeAt(i--)

//UTF-8编码为变长字节,使用实际的字节来记录

if(c <128) { // encode using utf-8

ba[--n] = c

}

else if((c >127) &&(c <2048)) {

ba[--n] = (c &63) | 128

ba[--n] = (c >>6) | 192

}

else {

ba[--n] = (c &63) | 128

ba[--n] = ((c >>6) &63) | 128

ba[--n] = (c >>12) | 224

}

}

//实际输入拼装结束,将下一位赋值为0标记结束

ba[--n] = 0

var rng = new SecureRandom()

var x = new Array()

//拼接随机非0字节

while(n >2) { // random non-zero pad

x[0] = 0

while(x[0] == 0) rng.nextBytes(x)

ba[--n] = x[0]

}

//这两位做简单的校验

ba[--n] = 2

ba[--n] = 0

return new BigInteger(ba)

}

该方法中对UTF-8字符进行了兼容,并且在拼装完实际输入的字符后,还拼装了随机的字节,使用拼装后的字符串去加密。由于每次拼装的结果是随机的,这样每次加密后的密文都不同。

2、调用方法:;

function RSAEncrypt(text) {

var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3)

if(m == null) return null

var c = this.doPublic(m)

if(c == null) return null

var h = c.toString(16)

if((h.length &1) == 0) return helse return "0" + h

}

代码如下,需要依赖一个jar包commons-codec-1.9.jar,用于Base64转换,请自行下载。

import org.apache.commons.codec.binary.Base64

import javax.crypto.BadPaddingException

import javax.crypto.Cipher

import javax.crypto.IllegalBlockSizeException

import java.io.ByteArrayOutputStream

import java.io.UnsupportedEncodingException

import java.security.*

import java.security.interfaces.RSAPrivateKey

import java.security.interfaces.RSAPublicKey

import java.security.spec.PKCS8EncodedKeySpec

import java.security.spec.X509EncodedKeySpec

public class RSAUtils {

    // 加密方式

    public static final String ALGORITHM = "RSA"

    // 签名算法

    private static final String SIGNATURE_ALGORITHM = "SHA1WithRSA"

    // 创建密钥对初始长度

    private static final int KEY_SIZE = 512

    // 字符编码格式

    private static final String CHARSET = "UTF-8"

    // RSA最大加密明文大小

    private static final int MAX_ENCRYPT_BLOCK = 117

    // RSA最大解密密文大小

    private static final int MAX_DECRYPT_BLOCK = 128

    private KeyFactory keyFactory

    public RSAUtils() throws NoSuchAlgorithmException {

        keyFactory = KeyFactory.getInstance(ALGORITHM)

    }

    /**

     * 私钥加密

     *

     * @param content    待加密字符串

     * @param privateKey 私钥

     * @return 加密后字符串(BASE64编码)

     */

    public String encryptByPrivateKey(String content, String privateKey) throws Exception {

        String result

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] keyBytes = new Base64().decode(privateKey)

            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)

            PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec)

            Cipher cipher = Cipher.getInstance(ALGORITHM)

            cipher.init(Cipher.ENCRYPT_MODE, pKey)

            byte[] data = content.getBytes(CHARSET)

            write2Stream(cipher, data, out)

            byte[] resultBytes = out.toByteArray()

            result = Base64.encodeBase64String(resultBytes)

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 公钥解密

     *

     * @param content   已加密字符串(BASE64加密)

     * @param publicKey 公钥

     * @return

     */

    public String decryptByPublicKey(String content, String publicKey) throws Exception {

        String result = ""

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] keyBytes = new Base64().decode(publicKey)

            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)

            PublicKey pKey = keyFactory.generatePublic(x509KeySpec)

            Cipher cipher = Cipher.getInstance(ALGORITHM)

            cipher.init(Cipher.DECRYPT_MODE, pKey)

            byte[] data = Base64.decodeBase64(content)

            write2Stream(cipher, data, out)

            byte[] resultBytes = out.toByteArray()

            result = new String(resultBytes)

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 公钥加密

     *

     * @param content   待加密字符串

     * @param publicKey 公钥

     * @return 加密后字符串(BASE64编码)

     */

    public String encryptByPublicKey(String content, String publicKey) throws Exception {

        String result = ""

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] keyBytes = new Base64().decode(publicKey)

            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes)

            PublicKey pKey = keyFactory.generatePublic(x509KeySpec)

            Cipher cipher = Cipher.getInstance(ALGORITHM)

            cipher.init(Cipher.ENCRYPT_MODE, pKey)

            byte[] data = content.getBytes(CHARSET)

            write2Stream(cipher,

                    data, out)

            byte[] resultBytes = out.toByteArray()

            result = Base64.encodeBase64String(resultBytes)

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 私钥解密

     *

     * @param content    已加密字符串

     * @param privateKey 私钥

     * @return 解密后字符串

     */

    public String decryptByPrivateKey(String content, String privateKey) throws Exception {

        String result = ""

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] keyBytes = new Base64().decode(privateKey)

            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)

            PrivateKey pKey = keyFactory.generatePrivate(pkcs8KeySpec)

            Cipher cipher = Cipher.getInstance(ALGORITHM)

            cipher.init(Cipher.DECRYPT_MODE, pKey)

            byte[] data = Base64.decodeBase64(content)

            write2Stream(cipher, data, out)

            byte[] resultBytes = out.toByteArray()

            result = new String(resultBytes)

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    private static void write2Stream(Cipher cipher, byte[] data, ByteArrayOutputStream out) throws

            BadPaddingException, IllegalBlockSizeException {

        int dataLen = data.length

        int offSet = 0

        byte[] cache

        int i = 0

        // 对数据分段解密

        while (dataLen - offSet > 0) {

            if (dataLen - offSet > MAX_DECRYPT_BLOCK) {

                cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK)

            } else {

                cache = cipher.doFinal(data, offSet, dataLen - offSet)

            }

            out.write(cache, 0, cache.length)

            i++

            offSet = i * MAX_DECRYPT_BLOCK

        }

    }

    /**

     * 用私钥对信息生成数字签名

     *

     * @param data       已加密数据

     * @param privateKey 私钥(BASE64编码)

     * @return sign

     */

    public String sign(String data, String privateKey) throws Exception {

        String result = ""

        try {

            byte[] keyBytes = new Base64().decode(privateKey)

            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes)

            PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec)

            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)

            signature.initSign(privateK)

            signature.update(parse2HexStr(data).getBytes(CHARSET))

            result = new Base64().encodeToString(signature.sign())

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 校验数字签名

     *

     * @param data      已加密数据

     * @param publicKey 公钥(BASE64编码)

     * @param sign      数字签名

     * @return

     * @throws Exception

     */

    public boolean verify(String data, String publicKey, String sign) throws Exception {

        boolean result

        try {

            byte[] keyBytes = new Base64().decode(publicKey)

            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes)

            PublicKey publicK = keyFactory.generatePublic(keySpec)

            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM)

            signature.initVerify(publicK)

            signature.update(parse2HexStr(data).getBytes(CHARSET))

            result = signature.verify(new Base64().decode(sign))

        } catch (Exception e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 将二进制转换成16进制

     *

     * @param data

     * @return

     */

    public static String parse2HexStr(String data) throws Exception {

        String result = ""

        try {

            byte[] buf = data.getBytes(CHARSET)

            StringBuffer sb = new StringBuffer()

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

                String hex = Integer.toHexString(buf[i] & 0xFF)

                if (hex.length() == 1) {

                    hex = '0' + hex

                }

                sb.append(hex.toUpperCase())

            }

            result = sb.toString()

        } catch (UnsupportedEncodingException e) {

            throw new Exception(e)

        }

        return result

    }

    /**

     * 生成公钥与私钥

     */

    public static void createKey() throws Exception {

        try {

            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM)

            keyPairGenerator.initialize(KEY_SIZE)

            KeyPair keyPair = keyPairGenerator.generateKeyPair()

            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic()

            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate()

            String publicKey = Base64.encodeBase64String(rsaPublicKey.getEncoded())

            String privateKey = Base64.encodeBase64String(rsaPrivateKey.getEncoded())

            System.out.println("publicKey=" + publicKey + "\nprivateKey=" + privateKey)

        } catch (NoSuchAlgorithmException e) {

            throw new Exception(e)

        }

    }

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

        String PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKeYGXH6Vz+m+KuL11RDRaNdHB4YQeZgqpJGPRSwBelgvEoHu2/fNs1bmgfJhI8lhr/o/Hy8EFB/I/DDyLcCcU4bCLtxpki8edC+KJR2WvyYfnVmWEe/3q2jSVKRf81868q9Cd3MMfrQPMsY4x0TQ0GtOf/nMSMbAltV2W8J86IfAgMBAAECgYEApYu4lr2SMW3ddJZNvQ42W4g9nfyYG9igpJx8+VJmhIDpfLbmjzsOBwvUupx0NHH9CNQ7k3qxItJzzf+W5C+lesEOAqdO5nahRZsL8BIDoxTEn2j+1GXkzQw3vqPY50xqRnZsoP5TyNNsOM7KYaOoz4VFMdVIFwoT3OKM5z7mxgECQQD51r17WZDSa/kucaH7gCOePxJPS6Ust0eVd5tBOMpFzD/VtziogSIWyhGKkLH0SyTJEe91CCpdpxufLSZgIiN5AkEAq7ojtvU4twak1N1/1qX+t8f5wD8i/8GU702PeCwkGI5ymrARq+W2yCuvU1bouXBhjKHV4KhafKYixdHUMg00VwJAYVUjpLaUESY3gbyLWqvlNHVl8LaLtwwAO17JgXNaei7Ef8JNtHf6i95VTyJn8cCEqEDwhSuVNb8wp6azWKh0IQJBAJHrcT2d0bt0IcvfCynRk0eG3WnGPG8mhu9w8GAk4ecb47YdtmZio5YjyK8AQnCQVdOyEJL9eyY/5XxCeBSvs7ECQQCKQ2f5HLDkkHvc6rlaHCJmqNRCS+CxhoaiaSPYLAac7WXmb614ACLECc86C/nkefTq0SNpUDVbGxVpJi9/FOUf"

        String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmBlx+lc/pviri9dUQ0WjXRweGEHmYKqSRj0UsAXpYLxKB7tv3zbNW5oHyYSPJYa/6Px8vBBQfyPww8i3AnFOGwi7caZIvHnQviiUdlr8mH51ZlhHv96to0lSkX/NfOvKvQndzDH60DzLGOMdE0NBrTn/5zEjGwJbVdlvCfOiHwIDAQAB"

        RSAUtils rsaUtil = new RSAUtils()

        String encryptByPublicKey = rsaUtil.encryptByPublicKey("你好!", PUBLIC_KEY)

        System.out.println(encryptByPublicKey)

        String decryptByPrivateKey = rsaUtil.decryptByPrivateKey(encryptByPublicKey, PRIVATE_KEY)

        System.out.println(decryptByPrivateKey)

        String encryptByPrivateKey = rsaUtil.encryptByPrivateKey("你好!", PRIVATE_KEY)

        System.out.println(encryptByPrivateKey)

        String decryptByPublicKey = rsaUtil.decryptByPublicKey(encryptByPrivateKey, PUBLIC_KEY)

        System.out.println(decryptByPublicKey)

        String sign = rsaUtil.sign("1234", PRIVATE_KEY)

        System.out.println("sign:" + sign)

        System.out.println(rsaUtil.verify("1234", PUBLIC_KEY, sign))

    }

}