美文网首页安全
加密解密的学习与理解

加密解密的学习与理解

作者: 庞哈哈哈12138 | 来源:发表于2017-06-13 11:04 被阅读0次

    数字摘要

    MD5

    Message Digest Algorithm MD5(消息摘要算法第五版),用于确保信息的完整一致。

    MD5算法具有以下特点:

    1. 压缩性:任意长度的数据,算出的MD5值长度都是固定的(128bit,32位十六进制)。
    2. 容易计算:从原数据计算出MD5值很容易。
    3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
    4. 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

    MD5作用:
    确定数据未被修改,保证文件(数据)的唯一性

    使用场景:
    用户的密码一般都是需要进行md5加密。

    注意:
    MD5是不可逆的,而且1KB的文件和1TB的文件的MD5值的长度是一样的。
    SHA1
    SHA1:160bit,40位十六进制

    SHA1和MD5的算法不一样,但是作用是一样的,都是用来保证文件的唯一性。

    Android中,androidsupport v4包的版本冲突,就是根据SHA1值来进行判断的。

    类似QQ、360的秒传功能,其实也是根据文件的SHA1来判断是否网盘已经有此正在发送的文件,若有,则无需用户再次上传。
    加盐
    加盐就是在密码的前面加入一些特殊字符,如:%&&%& 。

    场景:
    用户注册,密码111111 -> 对密码进行MD5 -> 保存密码的MD5值到数据库
    风险:
    假如数据库泄漏,现在网络上有很多MD5在线解析平台(其原理是将MD5值与一个庞大的数据库进行比对,最终得到原值),破坏者可以轻松得知用户的密码,用户信息遭到泄漏。

    解决方案:
    用户注册,密码111111 ->对密码加盐(&% + 111111 + ~%)->对加盐后的密码进行MD5 -> 保存MD5值到数据库

    加盐实际上就是在原值的基础上随机的添加一些佐料,密码经过加盐后再存储到数据库中,破坏者哪怕得到了数据库里的MD5值,也无法还原出正确的用户密码,保证了用户信息的安全性。
    加密解密
    Android中常见的加密解密
    对称加密算法
    对称加密算法指的是加密和解密操作只有一把密钥,如果密钥暴露,文件就会被暴露。

    常见的对称加密算法有:
    l DES:Data Encryption Standard(数据加密标准)
    l AES:Advanced Encryption Standard(高级加密标准),AES是在DES的基础上发展而来的

    对称加密算法的特点:
    l 加密速度比较快,可以加密比较大的文件
    l 密码可以自己指定
    非对称加密算法
    非对称的加密算法有两把钥匙(密钥对),分别为公钥和私钥,公钥可以给别人,私钥需要自己保存。

    常见加密:

    RSA

    加密解密方式:
    一方用来加密,则另一方就用来解密,成对使用
    l 公钥加密 -> 私钥解密
    l 私钥加密 -> 公钥解密
    数字签名:
    私钥签名-->公钥校验,其目的在于确定数据来源的不可否认性,确定数据的所属关系

    非对称加密算法的特点:
    l 加密速度比慢一些,但是安全系数比较高
    l 秘钥对需要程序生成,不能我们自己定义
    加密解密实例

    DES

    工具类:

    package com.billy.androidutils.utils.encrypt.des;
    
    import java.io.IOException;
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    
    import Decoder.BASE64Decoder;
    import Decoder.BASE64Encoder;
    
    public class Des {
    
        private final static String DES = "DES";
    
        public static void main(String[] args) throws Exception {
            String data = "大王盖地虎";
            String key = "wang!@#$%";
            System.err.println(encrypt(data, key));
    //    System.err.println(decrypt(encrypt(data, key), key));
    
        }
    
        /**
         * Description 根据键值进行加密
         * @param data
         * @param key  加密键byte数组
         * @return
         * @throws Exception
         */
        public static String encrypt(String data, String key) throws Exception {
            byte[] bt = encrypt(data.getBytes(), key.getBytes());
            String strs = new BASE64Encoder().encode(bt);
            return strs;
        }
    
        /**
         * Description 根据键值进行解密
         * @param data
         * @param key  加密键byte数组
         * @return
         * @throws IOException
         * @throws Exception
         */
        public static String decrypt(String data, String key) throws IOException, Exception {
            if (data == null)
                return null;
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] buf = decoder.decodeBuffer(data);
            byte[] bt = decrypt(buf, key.getBytes());
            return new String(bt);
        }
    
        /**
         * Description 根据键值进行加密
         * @param data
         * @param key  加密键byte数组
         * @return
         * @throws Exception
         */
        private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
            // 生成一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
    
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key);
    
            // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);
    
            // Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance(DES);
    
            // 用密钥初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
    
            return cipher.doFinal(data);
        }
    
        /**
         * Description 根据键值进行解密
         * @param data
         * @param key  加密键byte数组
         * @return
         * @throws Exception
         */
        private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
            // 生成一个可信任的随机数源
            SecureRandom sr = new SecureRandom();
    
            // 从原始密钥数据创建DESKeySpec对象
            DESKeySpec dks = new DESKeySpec(key);
    
            // 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);
    
            // Cipher对象实际完成解密操作
            Cipher cipher = Cipher.getInstance(DES);
    
            // 用密钥初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
    
            return cipher.doFinal(data);
        }
    }
    

    加密:

    */** 要被加密的数据 */*private String    data  = "需要加密的数据";*/**  秘钥 */*private String    key      = "%^&*()^&*(^&";*/**DES加密的结果 */*private String    mDesEncryptResult;
    ……
    //加密mDesEncryptResult=Des.*encrypt*(data, key);
    ……
    

    解密:

    //解密
    mDesDecryptResult = Des.*decrypt*(mDesEncryptResult, key);
    

    AES

    工具类:

    package com.billy.androidutils.utils.encrypt.aes;
    
    import android.annotation.SuppressLint;
    
    import java.security.SecureRandom;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    /**
     * AES加密
     */
    public class Aes {
    
        private final static String HEX = "0123456789ABCDEF";
    
        public static String encrypt(String data, String password) throws Exception {
            byte[] rawKey = getRawKey(password.getBytes());
            byte[] result = encrypt(rawKey, data.getBytes());
            return toHex(result);
        }
    
        public static String decrypt(String encrypted, String password) throws Exception {
            byte[] rawKey = getRawKey(password.getBytes());
            byte[] enc = toByte(encrypted);
            byte[] result = decrypt(rawKey, enc);
            return new String(result);
        }
    
        @SuppressLint("TrulyRandom")
        private static byte[] getRawKey(byte[] password) throws Exception {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
            sr.setSeed(password);
            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[] data) throws Exception {
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] encrypted = cipher.doFinal(data);
            return encrypted;
        }
    
        private static byte[] decrypt(byte[] raw, byte[] data) throws Exception {
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] decrypted = cipher.doFinal(data);
            return decrypted;
        }
    
        private 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;
        }
    
        private 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 static void appendHex(StringBuffer sb, byte b) {
            sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
        }
    }
    

    加密:

    */** 要被加密的数据 */*
    private String    data   = "需要加密的数据";
    */**  秘钥 */*
    private String  key  = "%^&*()^&*(^&";
    */** AES加密的结果 */*
    private String    mAesEncryptResult;
    ……
    // 加密mAesEncryptResult = Aes.*encrypt*(data,key);
    ……
    

    解密:

    // 解密String aesDecryptResult = Aes.*decrypt*(mAesEncryptResult,key);
    

    RSA

    在进行RSA加密解密之前,先要获取RSA的密钥对。不同于AES和DES,AES和DES的秘钥只有一个,而且可以自己指定,但是RSA的密钥对是代码生成的,不能由我们来定义。

    包含:
    KeyGen:密钥生成算法,PK,SK=KeyGen()Encrypt:加密算法,X=Encrypt(PK,M)Decrypt:解密算法,M=Decrypt(SK,X)Sign:签名算法,sign= Sign(SK,M)。Verify:验证算法,b= Verify(PK,sign,M)注:PK:公钥。SK:密钥。M:明文。X:密文。sign:明文的签名
    用途:
    a:公钥加密,私钥解密。用于传输数据的加密。b: 私钥签名,公钥验签。用于传输数据的完整性校验。优点:加密解密使用不同的密钥缺点:加密解密速度慢,资源消耗大

    工具类:

    package com.billy.androidutils.utils.encrypt.rsa;
    
    import java.io.ByteArrayOutputStream;
    import java.security.Key;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    
    import Decoder.BASE64Decoder;
    import Decoder.BASE64Encoder;
    
    public class RSACrypt {
    
       /**
        * 文件读取缓冲区大小
        */
       private static final int CACHE_SIZE = 1024;
    
       /**
        * <p>
        * BASE64字符串解码为二进制数据
        * </p>
        *
        * @param base64
        * @return
        * @throws Exception
        */
       public static byte[] decode(String base64) throws Exception {
           return new BASE64Decoder().decodeBuffer(base64);
       }
    
       /**
        * <p>
        * 二进制数据编码为BASE64字符串
        * </p>
        *
        * @param bytes
        * @return
        * @throws Exception
        */
       public static String encode(byte[] bytes) throws Exception {
           return new BASE64Encoder().encode(bytes);
       }
    
       /**
        * 加密算法RSA
        */
       // public static final String KEY_ALGORITHM = "RSA";
    
       public static final String KEY_ALGORITHM = "RSA";
    
       /**
        * 签名算法
        */
       public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
    
       /**
        * 获取公钥的key
        */
       private static final String PUBLIC_KEY = "RSAPublicKey";
    
       /**
        * 获取私钥的key
        */
       private static final String PRIVATE_KEY = "RSAPrivateKey";
    
       /**
        * RSA最大加密明文大小
        */
       private static final int MAX_ENCRYPT_BLOCK = 117;
    
       /**
        * RSA最大解密密文大小
        */
       private static final int MAX_DECRYPT_BLOCK = 128;
    
       /**
        * <p>
        * 生成密钥对(公钥和私钥)
        * </p>
        *
        * @return
        * @throws Exception
        */
       public static Map<String, Object> genKeyPair() throws Exception {
           KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
           keyPairGen.initialize(1024);
           KeyPair keyPair = keyPairGen.generateKeyPair();
           RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
           RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
           Map<String, Object> keyMap = new HashMap<String, Object>(2);
           keyMap.put(PUBLIC_KEY, publicKey);
           keyMap.put(PRIVATE_KEY, privateKey);
           return keyMap;
       }
    
       /**
        * <p>
        * 生成密钥对(公钥和私钥)
        * </p>
        *
        * @return
        * @throws Exception
        */
       public static Map<String, Object> genKeyPair(String seed) throws Exception {
           KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
           keyPairGen.initialize(1024);
           // SecureRandom secrand = new SecureRandom();
           // secrand.setSeed(seed.getBytes()); // 初始化随机产生器
           // keyPairGen.initialize(1024, secrand);
           KeyPair keyPair = keyPairGen.generateKeyPair();
           RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
           RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
           Map<String, Object> keyMap = new HashMap<String, Object>(2);
           keyMap.put(PUBLIC_KEY, publicKey);
           keyMap.put(PRIVATE_KEY, privateKey);
           return keyMap;
       }
    
       /**
        * <p>
        * 用私钥对信息生成数字签名
        * </p>
        *
        * @param data
        *            已加密数据
        * @param privateKey
        *            私钥(BASE64编码)
        *
        * @return
        * @throws Exception
        */
       public static String sign(byte[] data, String privateKey) throws Exception {
           byte[] keyBytes = decode(privateKey);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
           Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
           signature.initSign(privateK);
           signature.update(data);
           return encode(signature.sign());
       }
    
       /**
        * <p>
        * 校验数字签名
        * </p>
        *
        * @param data
        *            已加密数据
        * @param publicKey
        *            公钥(BASE64编码)
        * @param sign
        *            数字签名
        *
        * @return
        * @throws Exception
        *
        */
       public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
           byte[] keyBytes = decode(publicKey);
           X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
    
           PublicKey publicK = keyFactory.generatePublic(keySpec);
           Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
           signature.initVerify(publicK);
           signature.update(data);
           return signature.verify(decode(sign));
       }
    
       /**
        * <P>
        * 私钥解密
        * </p>
        *
        * @param encryptedData
        *            已加密数据
        * @param privateKey
        *            私钥(BASE64编码)
        * @return
        * @throws Exception
        */
       public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
           byte[] keyBytes = decode(privateKey);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
    //     Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    
           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    
           cipher.init(Cipher.DECRYPT_MODE, privateK);
           int inputLen = encryptedData.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段解密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                   cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_DECRYPT_BLOCK;
           }
           byte[] decryptedData = out.toByteArray();
           out.close();
           return decryptedData;
       }
    
       /**
        * <p>
        * 公钥解密
        * </p>
        *
        * @param encryptedData
        *            已加密数据
        * @param publicKey
        *            公钥(BASE64编码)
        * @return
        * @throws Exception
        */
       public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {
           byte[] keyBytes = decode(publicKey);
           X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key publicK = keyFactory.generatePublic(x509KeySpec);
           // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    
           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
           cipher.init(Cipher.DECRYPT_MODE, publicK);
           int inputLen = encryptedData.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段解密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                   cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_DECRYPT_BLOCK;
           }
           byte[] decryptedData = out.toByteArray();
           out.close();
           return decryptedData;
       }
    
       /**
        * <p>
        * 公钥加密
        * </p>
        *
        * @param data
        *            源数据
        * @param publicKey
        *            公钥(BASE64编码)
        * @return
        * @throws Exception
        */
       public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
           byte[] keyBytes = decode(publicKey);
           X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key publicK = keyFactory.generatePublic(x509KeySpec);
           // 对数据加密
           // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    
           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
    
           cipher.init(Cipher.ENCRYPT_MODE, publicK);
           int inputLen = data.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段加密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                   cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(data, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_ENCRYPT_BLOCK;
           }
           byte[] encryptedData = out.toByteArray();
           out.close();
           return encryptedData;
       }
    
       /**
        * <p>
        * 私钥加密
        * </p>
        *
        * @param data
        *            源数据
        * @param privateKey
        *            私钥(BASE64编码)
        * @return
        * @throws Exception
        */
       public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {
           byte[] keyBytes = decode(privateKey);
           PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
           KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
           Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
           // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
           Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
           cipher.init(Cipher.ENCRYPT_MODE, privateK);
           int inputLen = data.length;
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           int offSet = 0;
           byte[] cache;
           int i = 0;
           // 对数据分段加密
           while (inputLen - offSet > 0) {
               if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                   cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
               } else {
                   cache = cipher.doFinal(data, offSet, inputLen - offSet);
               }
               out.write(cache, 0, cache.length);
               i++;
               offSet = i * MAX_ENCRYPT_BLOCK;
           }
           byte[] encryptedData = out.toByteArray();
           out.close();
           return encryptedData;
       }
    
       /**
        * <p>
        * 获取私钥
        * </p>
        *
        * @param keyMap
        *            密钥对
        * @return
        * @throws Exception
        */
       public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
           Key key = (Key) keyMap.get(PRIVATE_KEY);
           return encode(key.getEncoded());
       }
    
       /**
        * <p>
        * 获取公钥
        * </p>
        *
        * @param keyMap
        *            密钥对
        * @return
        * @throws Exception
        */
       public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
           Key key = (Key) keyMap.get(PUBLIC_KEY);
           return encode(key.getEncoded());
       }
    
    }
    

    生成RSA密钥对:

    /** RSA加密的公钥 */
    private String mPublicKey;
    
    /** RSA加密的私钥 */
    private String mPrivateKey;
    ……
    /**
     *  生成RSA密钥对
     */
    private void generateKeyPair() {
        // 通过代码生成rsa对应的公钥和私钥
        try {
            // 1.生成秘钥对
            Map<String, Object> keyPair = RSACrypt.genKeyPair();
            // 2.得到公钥
            mPublicKey = RSACrypt.getPublicKey(keyPair);
            // 3.得到私钥
            mPrivateKey = RSACrypt.getPrivateKey(keyPair);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    加密:

    
    /** RSA私钥加密的结果 */
    private byte[] mRsaEncryptByPrivateKeys;
    ……
    // 加密
    mRsaEncryptByPrivateKeys = RSACrypt.encryptByPrivateKey(data.getBytes(), mPrivateKey);
    // 只能调用RSACrypt里面的方法把byte[]-->String
    String rsaEncodeResult = RSACrypt.encode(mRsaEncryptByPrivateKeys);
    
    

    解密:

    
    // 解密
    byte[] decryptByPublicKey = RSACrypt.decryptByPublicKey(mRsaEncryptByPrivateKeys, mPublicKey);
    // 这里可以通过new String把byte[]-->String
    String rsaDecodeResult = new String(decryptByPublicKey);
    

    RSA公钥互换
    公钥互换指的是两个人或者两个机构互相交换公钥,换句话就是说两个密钥对的持有者相互的置换公钥。

    场景:
    A机构有私钥“A private key”和公钥“A public key”;
    B机构有私钥“B private key”和“B public key”;
    A机构和B机构互相置换了公钥;
    置换后A机构持有:“A private key”、“A public key”、“B public key”;
    置换后B机构持有:“B private key”、“B public key”、“A public key”;

    当A机构要向B机构发送数据的时候,可以用“A private key”或者“B public key”对数据进行加密,B机构就可以用”A public key”或者“B private key”对加密的数据进行解密了。

    公钥互换的作用:

    1. 加密解密
    2. 签名校验
      数字签名
      数字签名的作用就是确定数据来源的不可否认性,确定数据的所属关系(其实就是确定privatekey在哪里)。

    注意:
    数字签名只能用私钥进行加密,用公钥进行校验

    原理:
    数字签名必须用私钥来做加密,那么校验的时候就只能用公钥。
    而私钥是由个人自己保存的,是不能告诉外界的,能告诉给外界的只有自己的公钥。
    因此,若一个加密的数据能够被一个公钥校验,那么就可以唯一的确定这个加密数据的私钥来自哪里。

    public class Test {
      public static void main(String[] args) {
         try {
               // 生成密钥对
            Map<String, Object> genKeyPair = RSACrypt.genKeyPair();
            String privateKey = RSACrypt.getPrivateKey(genKeyPair);
            String publicKey = RSACrypt.getPublicKey(genKeyPair);
    
            System.out.println("privateKey:\r\n" + privateKey);
            System.out.println("publicKey:\r\n" + publicKey);
    
            System.out.println("--------------开始签名,验证--------------");
               // 签名前的源数据
            String str = "A同学向B同学了借了100w";
            String str1 = "ahhhhhhhha";
    
            // 开始对数据进行签名
            byte[] data = str.getBytes();
            // 获取签名后的数据
            String sign = RSACrypt.sign(data, privateKey);
            System.out.println("sign\r\n:" + sign);
    
            // 对签名的数据进行校验
            // boolean verify = RSACrypt.verify(原始内容,公钥, 签名之后的内容);
            boolean verify = RSACrypt.verify(data, publicKey, sign);
    
            // 是否校验成功
            if (verify) {
               System.out.println("verfiy成功,确实是a同学给我打的欠条");
            } else {
               System.out.println("verfiy不成功");
            } 
         } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
         } catch (Exception e) {
            e.printStackTrace();
         }
      }
    }
    

    相关文章

      网友评论

        本文标题:加密解密的学习与理解

        本文链接:https://www.haomeiwen.com/subject/epkdqxtx.html