精华内容
下载资源
问答
  • 1、常用的加密算法分类 常见的加密算法可以分成五类: 对称加密算法、非对称加密算法和、Hash 算法(也称摘要算法)、数字签名(Hash&RSA)和数字证书(Hash&RSA&CA)。 1)对称加密算法...

    1、常用的加密算法分类

    常见的加密算法可以分成五类:

    对称加密算法、非对称加密算法和、Hash 算法(也称摘要算法)、数字签名(Hash&RSA)和数字证书(Hash&RSA&CA)。

    1)对称加密算法

    指加密和解密使用相同密钥的加密算法。

    对称加密算法的优点在于加解密的高速度和使用长密钥时的难破解性。

    假设两个用户需要使用对称加密方法加密然后交换数据,则用户最少需要 2 个密钥并交换使用,如果企业内用户有 n 个,则整个企业共需要 n×(n-1) 个密钥,密钥的生成和分发将成为企业信息部门的恶梦。

    对称加密算法的安全性取决于加密密钥的保存情况,但要求企业中每一个持有密钥的人都保守秘密是不可能的,他们通常会有意无意的把密钥泄漏出去——如果一个用户使用的密钥被入侵者所获得,入侵者便可以读取该用户密钥加密的所有文档。

    常见的对称加密算法:

    DES、3DES、DESX、Blowfish、IDEA、RC4、RC5、RC6 和 AES

    对称加密算法用来对敏感数据等信息进行加密,常用的算法包括:

    DES(Data Encryption Standard):数据加密标准,速度较快,适用于加密大量数据的场合;

    3DES(Triple DES):是基于 DES,但强度更高;

    AES(Advanced Encryption Standard):高级加密标准,是下一代的加密算法标准,速度快,安全级别高。

    2)非对称加密算法

    指加密和解密使用不同密钥的加密算法,也称为公私钥加密。

    假设两个用户要加密交换数据,双方交换公钥,使用时一方用对方的公钥加密,另一方即可用自己的私钥解密。

    如果企业中有 n 个用户,企业需要生成 n 对密钥,并分发 n 个公钥。由于公钥是可以公开的,用户只要保管好自己的私钥即可,因此加密密钥的分发将变得十分简单。

    同时,由于每个用户的私钥是唯一的,其他用户除了可以可以通过信息发送者的公钥来验证信息的来源是否真实,还可以确保发送者无法否认曾发送过该信息。

    非对称加密的缺点是加解密速度要远远慢于对称加密,在某些极端情况下,甚至能比非对称加密慢上 1000 倍。

    常见的非对称加密算法:

    RSA、ECC(移动设备用)、Diffie-Hellman、El Gamal、DSA(数字签名用)

    RSA:由 RSA 公司发明,是一个支持变长密钥的公共密钥算法,需要加密的文件块的长度也是可变的;

    DSA(Digital Signature Algorithm):数字签名算法,是一种标准的 DSS(数字签名标准);

    ECC(Elliptic Curves Cryptography):椭圆曲线密码编码学。

    ECC 和 RSA 相比,在许多方面都有对绝对的优势,主要体现在以下方面:

    抗攻击性强:相同的密钥长度,其抗攻击性要强很多倍;

    计算量小,处理速度快,ECC 总的速度比 RSA、DSA 要快得多;

    存储空间占用小,ECC 的密钥尺寸和系统参数与 RSA、DSA 相比要小得多,意味着它所占的存贮空间要小得多,这对于加密算法在 IC 卡上的应用具有特别重要的意义;

    带宽要求低,当对长消息进行加解密时,三类密码系统有相同的带宽要求,但应用于短消息时 ECC 带宽要求却低得多,带宽要求低使 ECC 在无线网络领域具有广泛的应用前景。

    3)Hash 算法

    Hash 算法特别的地方在于它是一种单向算法,用户可以通过 Hash 算法对目标信息生成一段特定长度的唯一的 Hash 值,却不能通过这个 Hash 值重新获得目标信息。

    Hash(明文)--> 固定长度的摘要

    因此 Hash 算法常用在不可还原的密码存储、信息完整性校验等。

    特点:

    无论明文多长,计算出来的摘要长度总是固定的。hash(‘a’)和hash(‘aaaaaaaaaaa’)形成的摘要长度是一样的;

    一般明文不同,计算出来的摘要也不同。也就是相同的明文,计算出来的摘要是一样的,不同的明文形成的摘要一般是不一样(好的 Hash 函数不会发生碰撞);

    只能进行正向的消息摘要,也就是说从消息摘要中不能恢复成原来的明文。

    常见的 Hash 算法:

    MD2、MD4、MD5、HAVAL、SHA、SHA-1、HMAC、HMAC-MD5、HMAC-SHA1

    4)数字签名:将明文进行摘要,然后再通过私钥进行加密的结果

    MD5&RSA 算法和 SHA1&RSA 算法

    A 给 B 发送信息,A 生成公钥和私钥并将公钥公开;

    A 对发送消息进行数字摘要算法(Hash),然后再通过私钥进行加密;

    A 将明文和加密后的密文发送给 B;

    B 收到后,对密文用公钥进行解密,获得数据 C,再对明文进行摘要算法,获得数据 D,然后对比 C 和 D,这样就能确认 A 的身份。

    B 收到 A 的文件,B 想确认是 A 发送的,那么可以根据数字签名方式,根据 A 的公钥进行解密然后比较,因为 A 的私钥是不公开的,这样匹配成功就能确认是 A 发送的。

    5)数字证书

    A 给 B 发送消息,A生 成公钥和私钥;

    A 将公钥、公钥持有者、签名算法和过期时间等信息发送给 CA(数字证书认证机构);

    CA 认可信息之后,通过 CA 的私钥进行签名,这时候数字证书就产生了;

    接着 A 将明文、明文数字签名和数字证书一起发送给 B;

    B 接受到后,通过 CA 的公钥进行解密,进行第一次校验,校验数字证书;

    验证成功后,进行第二次检验,提取数字证书中的公钥,对密文进行解密。

    在数字签名的基础上,再发送一个数字证书,这样的话接收方不需要维护一个公钥库,通过 CA 验证后在数字证书提取,获得公钥。

    总结:

    加密算法的效能通常可以按照算法本身的复杂程度、密钥长度(密钥越长越安全)和加解密速度等来衡量。

    上述的算法中,除了 DES 密钥长度不够、MD2 速度较慢已逐渐被淘汰外,其他算法仍在目前的加密系统产品中使用。

    2、加密算法的选择

    1)由于非对称加密算法的运行速度比对称加密算法的速度慢很多,当我们需要加密大量的数据时,建议采用对称加密算法,提高加解密速度;

    2)对称加密算法不能实现签名,因此签名只能非对称算法;

    3)由于对称加密算法的密钥管理是一个复杂的过程,密钥的管理直接决定着他的安全性,因此当数据量很小时,我们可以考虑采用非对称加密算法。

    4)在实际的操作过程中,我们通常采用的方式是:

    采用非对称加密算法管理对称算法的密钥,然后用对称加密算法加密数据,这样我们就集成了两类加密算法的优点,既实现了加密速度快的优点,又实现了安全方便管理密钥的优点。

    3、如何选择采用多少位的密钥

    一般来说,密钥越长,运行的速度就越慢,应该根据的我们实际需要的安全级别来选择,一般来说,RSA 建议采用 1024 位的数字,ECC 建议采用 160 位,AES 采用 128 为即可,对于安全性较高的场合需要使用相应长度的秘钥。

    4、加密算法应用

    1)保密通信:

    保密通信是密码学产生的动因,使用公私钥密码体制进行保密通信时,信息接收者只有知道对应的密钥才可以解密该信息。

    2)数字签名:

    数字签名技术可以代替传统的手写签名,而且从安全的角度考虑,数字签名具有很好的防伪造功能,在政府机关、军事领域、商业领域有广泛的应用环境。

    3)秘密共享:

    秘密共享技术是指将一个秘密信息利用密码技术分拆成 n 个称为共享因子的信息,分发给 n 个成员,只有 k(k≤n) 个合法成员的共享因子才可以恢复该秘密信息,其中任何一个或 m(m≤k) 个成员合作都不知道该秘密信息。

    利用秘密共享技术可以控制任何需要多个人共同控制的秘密信息、命令等。

    4)认证功能:

    在公开的信道上进行敏感信息的传输,采用签名技术实现对消息的真实性、完整性进行验证,通过验证公钥证书实现对通信主体的身份验证。

    5)密钥管理:

    密钥是保密系统中更为脆弱而重要的环节,公钥密码体制是解决密钥管理工作的有力工具;

    利用公钥密码体制进行密钥协商和产生,保密通信双方不需要事先共享秘密信息;

    利用公钥密码体制进行密钥分发、保护、密钥托管、密钥恢复等。

    6)基于公钥密码体制可以实现以上通用功能以外,还可以设计实现以下的系统:

    安全电子商务系统、电子现金系统、电子选举系统、电子招投标系统、电子彩票系统等。

     
    refer:

    https://www.cnblogs.com/colife/p/5566789.html

    https://www.cnblogs.com/-new/p/7199837.html

     

    展开全文
  • 常见的几种安全加密算法

    千次阅读 2017-11-17 10:58:12
    本文整理了常见的安全算法,包括MD5、SHA、DES、AES、RSA等,并写了完整的工具类(Java 版),工具类包含测试,大家可以放心使用。一、数字摘要算法 数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定...

    本文整理了常见的安全算法,包括MD5、SHA、DES、AES、RSA等,并写了完整的工具类(Java 版),工具类包含测试,大家可以放心使用。

    一、数字摘要算法

    数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash函数对消息进行计算而产生。如果消息在传递的途中改变了,接收者通过对收到消息采用相同的Hash重新计算,新产生的摘要与原摘要进行比较,就可知道消息是否被篡改了,因此消息摘要能够验证消息的完整性。消息摘要采用单向Hash函数将需要计算的内容”摘要”成固定长度的串,这个串亦称为数字指纹。这个串有固定的长度,且不同的明文摘要成密文,其结果总是不同的(相对的),而同样的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是”真身”的”指纹”了。

    1. Md5

    MD5即Message Digest Algorithm 5(信息摘要算法5),是数字摘要算法一种实现,用于确保信息传输完整性和一致性,摘要长度为128位。 MD5由MD4、 MD3、 MD2改进而来,主要增强算法复杂度和不可逆性,该算法因其普遍、稳定、快速的特点,在产业界得到了极为广泛的使用,目前主流的编程语言普遍都已有MD5算法实现。

    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    /**
     * Message Digest Algorithm 5(信息摘要算法5)
     */
    public class MD5Util {
        /**
         * Constructs the MD5Util object and sets the string whose MD5Util is to be
         * computed.
         * 
         * @param inStr
         *    the <code>String</code> whose MD5Util is to be computed
         */
    
    
        public final static String COMMON_KEY="zhongzhuoxin#@!321";
        public MD5Util() {
    
        }
    
        public final static String str2MD5(String inStr) {
            char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    'a', 'b', 'c', 'd', 'e', 'f' };
            try {
                byte[] strTemp = inStr.getBytes("UTF-8");
                MessageDigest mdTemp = MessageDigest.getInstance("MD5");
                mdTemp.update(strTemp);
                byte[] md = mdTemp.digest();
                int j = md.length;
                char str[] = new char[j * 2];
                int k = 0;
                for (int i = 0; i < j; i++) {
                    byte byte0 = md[i];
                    str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                    str[k++] = hexDigits[byte0 & 0xf];
                }
                return new String(str);
            } catch (Exception e) {
                return null;
            }
        }
    
    
    
    
        //--MD5Util
        private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
    
        public static String toHexString(byte[] b) { // String to byte
            StringBuilder sb = new StringBuilder(b.length * 2);
            for (int i = 0; i < b.length; i++) {
                sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
                sb.append(HEX_DIGITS[b[i] & 0x0f]);
            }
            return sb.toString();
        }
    
        public static String AndroidMd5(String s) {
            try {
                // Create MD5Util Hash
                MessageDigest digest = MessageDigest
                        .getInstance("MD5");
                digest.update(s.getBytes());
                byte messageDigest[] = digest.digest();
    
                return toHexString(messageDigest);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
    
            return "";
        }
    
        public static void main(String[] args) {
    
            String m = MD5Util.str2MD5("swwwwwwwwwwdkinner");
    
            System.out.print(m.length() + "    ");
            System.out.println(m);
    
        }
    }

    2.SHA

    SHA的全称是Secure Hash Algorithm,即安全散列算法。 1993年,安全散列算法(SHA)由美国国家标准和技术协会(NIST)提出,并作为联邦信息处理标准(FIPS PUB 180)公布, 1995年又发布了一个修订版FIPS PUB 180-1,通常称之为SHA-1。 SHA-1是基于MD4算法的,现在已成为公认的最安全的散列算法之一,并被广泛使用。SHA-1算法生成的摘要信息的长度为160位,由于生成的摘要信息更长,运算的过程更加复杂,在相同的硬件上, SHA-1的运行速度比MD5更慢,但是也更为安全。

    
    
    import com.google.common.base.Strings;
    
    import java.security.MessageDigest;
    
    /**
     * SHA的全称是Secure Hash Algorithm,即安全散列算法
     * Created by fangzhipeng on 2017/3/21.
     */
    public class SHAUtil {
    
        /**
         * 定义加密方式
         */
        private final static String KEY_SHA = "SHA";
        private final static String KEY_SHA1 = "SHA-1";
        /**
         * 全局数组
         */
        private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
                "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    
        /**
         * 构造函数
         */
        public SHAUtil() {
    
        }
    
        /**
         * SHA 加密
         * @param data 需要加密的字节数组
         * @return 加密之后的字节数组
         * @throws Exception
         */
        public static byte[] encryptSHA(byte[] data) throws Exception {
            // 创建具有指定算法名称的信息摘要
    //        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
            MessageDigest sha = MessageDigest.getInstance(KEY_SHA1);
            // 使用指定的字节数组对摘要进行最后更新
            sha.update(data);
            // 完成摘要计算并返回
            return sha.digest();
        }
    
        /**
         * SHA 加密
         * @param data 需要加密的字符串
         * @return 加密之后的字符串
         * @throws Exception
         */
        public static String encryptSHA(String data) throws Exception {
            // 验证传入的字符串
            if (Strings.isNullOrEmpty(data)) {
                return "";
            }
            // 创建具有指定算法名称的信息摘要
            MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
            // 使用指定的字节数组对摘要进行最后更新
            sha.update(data.getBytes());
            // 完成摘要计算
            byte[] bytes = sha.digest();
            // 将得到的字节数组变成字符串返回
            return byteArrayToHexString(bytes);
        }
    
        /**
         * 将一个字节转化成十六进制形式的字符串
         * @param b 字节数组
         * @return 字符串
         */
        private static String byteToHexString(byte b) {
            int ret = b;
            //System.out.println("ret = " + ret);
            if (ret < 0) {
                ret += 256;
            }
            int m = ret / 16;
            int n = ret % 16;
            return hexDigits[m] + hexDigits[n];
        }
    
        /**
         * 转换字节数组为十六进制字符串
         * @param bytes 字节数组
         * @return 十六进制字符串
         */
        private static String byteArrayToHexString(byte[] bytes) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < bytes.length; i++) {
                sb.append(byteToHexString(bytes[i]));
            }
            return sb.toString();
        }
    
        /**
         * 测试方法
         * @param args
         */
        public static void main(String[] args) throws Exception {
            String key = "123";
            System.out.println(encryptSHA(key));
        }
    }

    二、对称加密

    对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,生成复杂的加密密文进行发送,数据接收方收到密文后,若想读取原文,则需要使用加密使用的密钥及相同算法的逆算法对加密的密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发送和接收双方都使用这个密钥对数据进行加密和解密,这就要求加密和解密方事先都必须知道加密的密钥。

    1. DES算法

    1973 年,美国国家标准局(NBS)在认识到建立数据保护标准既明显又急迫的情况下,开始征集联邦数据加密标准的方案。 1975 年3月17日, NBS公布了IBM公司提供的密码算法,以标准建议的形式在全国范围内征求意见。经过两年多的公开讨论之后, 1977 年7月15日, NBS宣布接受这建议,作为联邦信息处理标准46 号数据加密标准(Data Encryptin Standard),即DES正式颁布,供商业界和非国防性政府部门使用。DES算法属于对称加密算法,明文按64位进行分组,密钥长64位,但事实上只有56位参与DES运算(第8、 16、 24、 32、 40、 48、 56、 64位是校验位,使得每个密钥都有奇数个1),分组后的明文和56位的密钥按位替代或交换的方法形成密文。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解,因此演变出了3DES算法。 3DES是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密,是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 sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    /**
     * Data Encryptin Standard
     * 数据加密标准
     */
    public class DESUtil {
    
    
        private final static String DES = "DES";
    
        /**
         * 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 Exception,
                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);
        }
    
        public static void main(String[]args)throws Exception{
           String  sStr=encrypt("122222112222:12343232323:jajwwwwslwskwkkwksk","wew2323w233321ws233w");
           System.out.println(sStr);
           String mStr=decrypt(sStr,"wew2323w233321ws233w");
           System.out.println(mStr);
        }
    }

    2. AES

    AES的全称是Advanced Encryption Standard,即高级加密标准,该算法由比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,又称Rijndael加密算法,是美国联邦政府采用的一种对称加密标准,这个标准用来替代原先的DES算法,已经广为全世界所使用,已然成为对称加密算法中最流行的算法之一。AES算法作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活等优点,设计有三个密钥长度:128,192,256位,比DES算法的加密强度更高,更为安全。

    
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Base64;
    import java.util.Scanner;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    import sun.misc.BASE64Decoder;
    import sun.misc.BASE64Encoder;
    
    /**
     * Created by fangzhipeng on 2017/3/21.
     */
    public class AESUtil {
    
        static  byte[]  key = "w@#$4@#$s^&3*&^4".getBytes();
        final static String algorithm="AES";
    
        public static String encrypt(String data){
    
            byte[] dataToSend = data.getBytes();
            Cipher c = null;
            try {
                c = Cipher.getInstance(algorithm);
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            SecretKeySpec k =  new SecretKeySpec(key, algorithm);
            try {
                c.init(Cipher.ENCRYPT_MODE, k);
            } catch (InvalidKeyException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] encryptedData = "".getBytes();
            try {
                encryptedData = c.doFinal(dataToSend);
            } catch (IllegalBlockSizeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (BadPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            byte[] encryptedByteValue =     Base64.getEncoder().encode(encryptedData);
            return  new String(encryptedByteValue);//.toString();
        }
    
        public static String decrypt(String data){
    
            byte[] encryptedData  =  Base64.getDecoder().decode(data);
            Cipher c = null;
            try {
                c = Cipher.getInstance(algorithm);
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            SecretKeySpec k =
                    new SecretKeySpec(key, algorithm);
            try {
                c.init(Cipher.DECRYPT_MODE, k);
            } catch (InvalidKeyException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            byte[] decrypted = null;
            try {
                decrypted = c.doFinal(encryptedData);
            } catch (IllegalBlockSizeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (BadPaddingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return new String(decrypted);
        }
    
        public static void main(String[] args){
            String password=encrypt("12233440988:1239874389888:dd333");
            System.out.println(password);
            System.out.println(decrypt(password));
        }
    }
    

    三、非对称加密

    非对称加密算法又称为公开密钥加密算法,它需要两个密钥,一个称为公开密钥(public key),即公钥,另一个称为私有密钥(private key),即私钥。公钥与私钥需要配对使用,如果用公钥对数据进行加密,只有用对应的私钥才能进行解密,而如果使用私钥对数据进行加密,那么只有用对应的公钥才能进行解密。因为加密和解密使用的是两个不同的密钥,所以这种算法称为非对称加密算法。非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将其中的一把作为公钥向其它人公开,得到该公钥的乙方使用该密钥对机密信息进行加密后再发送给甲方,甲方再使用自己保存的另一把专用密钥,即私钥,对加密后的信息进行解密。

    1.RSA

    RSA非对称加密算法是1977年由Ron Rivest、 Adi Shamirh和LenAdleman开发的, RSA取名来自开发他们三者的名字。 RSA是目前最有影响力的非对称加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。 RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但反过来想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

    
    /**
     * Created by fangzhipeng on 2017/3/21.
     * RSA :RSA非对称加密算法是1977年由Ron Rivest、 Adi Shamirh和LenAdleman开发   *  的, RSA取名来
     *  自开发他们三者的名字。
     * 参考:http://blog.csdn.net/wangqiuyun/article/details/42143957
     */
    
    import java.io.*;
    import java.security.InvalidKeyException;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    public class RSAUtil {
    
    
        /**
         * 字节数据转字符串专用集合
         */
        private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
                '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    
        /**
         * 随机生成密钥对
         */
        public static void genKeyPair(String filePath) {
            // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
            KeyPairGenerator keyPairGen = null;
            try {
                keyPairGen = KeyPairGenerator.getInstance("RSA");
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGen.initialize(1024,new SecureRandom());
            // 生成一个密钥对,保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 得到私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 得到公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            try {
                // 得到公钥字符串
                // 得到私钥字符串
                String privateKeyString =new String( Base64.getEncoder().encode(privateKey.getEncoded()));
                String publicKeyString =new String( Base64.getEncoder().encode(publicKey.getEncoded()));
                // 将密钥对写入到文件
    
                File file1=new File(filePath + "publicKey.keystore");
                File file2=new File(filePath + "privateKey.keystore");
                if(!file1.exists()) {
                    file1.createNewFile();
                }
                if(!file2.exists()) {
                    file2.createNewFile();
                }
                FileWriter pubfw = new FileWriter(filePath + "/publicKey.keystore");
                FileWriter prifw = new FileWriter(filePath + "/privateKey.keystore");
                BufferedWriter pubbw = new BufferedWriter(pubfw);
                BufferedWriter pribw = new BufferedWriter(prifw);
                pubbw.write(publicKeyString);
                pribw.write(privateKeyString);
                pubbw.flush();
                pubbw.close();
                pubfw.close();
                pribw.flush();
                pribw.close();
                prifw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 从文件中输入流中加载公钥
         *
         * @param
         *
         * @throws Exception
         *             加载公钥时产生的异常
         */
        public static String loadPublicKeyByFile(String path) throws Exception {
            try {
                BufferedReader br = new BufferedReader(new FileReader(path
                        + "/publicKey.keystore"));
                String readLine = null;
                StringBuilder sb = new StringBuilder();
                while ((readLine = br.readLine()) != null) {
                    sb.append(readLine);
                }
                br.close();
                return sb.toString();
            } catch (IOException e) {
                throw new Exception("公钥数据流读取错误");
            } catch (NullPointerException e) {
                throw new Exception("公钥输入流为空");
            }
        }
    
        /**
         * 从字符串中加载公钥
         *
         * @param publicKeyStr
         *            公钥数据字符串
         * @throws Exception
         *             加载公钥时产生的异常
         */
        public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
                throws Exception {
            try {
                byte[] buffer = Base64.getDecoder().decode(publicKeyStr);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
                return (RSAPublicKey) keyFactory.generatePublic(keySpec);
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此算法");
            } catch (InvalidKeySpecException e) {
                throw new Exception("公钥非法");
            } catch (NullPointerException e) {
                throw new Exception("公钥数据为空");
            }
        }
    
        /**
         * 从文件中加载私钥
         *
         * @param
         *
         * @return 是否成功
         * @throws Exception
         */
        public static String loadPrivateKeyByFile(String path) throws Exception {
            try {
                BufferedReader br = new BufferedReader(new FileReader(path
                        + "/privateKey.keystore"));
                String readLine = null;
                StringBuilder sb = new StringBuilder();
                while ((readLine = br.readLine()) != null) {
                    sb.append(readLine);
                }
                br.close();
                return sb.toString();
            } catch (IOException e) {
                throw new Exception("私钥数据读取错误");
            } catch (NullPointerException e) {
                throw new Exception("私钥输入流为空");
            }
        }
    
        public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
                throws Exception {
            try {
                byte[] buffer = Base64.getDecoder().decode(privateKeyStr);
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此算法");
            } catch (InvalidKeySpecException e) {
                throw new Exception("私钥非法");
            } catch (NullPointerException e) {
                throw new Exception("私钥数据为空");
            }
        }
    
        /**
         * 公钥加密过程
         *
         * @param publicKey
         *            公钥
         * @param plainTextData
         *            明文数据
         * @return
         * @throws Exception
         *             加密过程中的异常信息
         */
        public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
                throws Exception {
            if (publicKey == null) {
                throw new Exception("加密公钥为空, 请设置");
            }
            Cipher cipher = null;
            try {
                // 使用默认RSA
                cipher = Cipher.getInstance("RSA");
                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                byte[] output = cipher.doFinal(plainTextData);
                return output;
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此加密算法");
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
                return null;
            } catch (InvalidKeyException e) {
                throw new Exception("加密公钥非法,请检查");
            } catch (IllegalBlockSizeException e) {
                throw new Exception("明文长度非法");
            } catch (BadPaddingException e) {
                throw new Exception("明文数据已损坏");
            }
        }
    
        /**
         * 私钥加密过程
         *
         * @param privateKey
         *            私钥
         * @param plainTextData
         *            明文数据
         * @return
         * @throws Exception
         *             加密过程中的异常信息
         */
        public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
                throws Exception {
            if (privateKey == null) {
                throw new Exception("加密私钥为空, 请设置");
            }
            Cipher cipher = null;
            try {
                // 使用默认RSA
                cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                byte[] output = cipher.doFinal(plainTextData);
                return output;
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此加密算法");
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
                return null;
            } catch (InvalidKeyException e) {
                throw new Exception("加密私钥非法,请检查");
            } catch (IllegalBlockSizeException e) {
                throw new Exception("明文长度非法");
            } catch (BadPaddingException e) {
                throw new Exception("明文数据已损坏");
            }
        }
    
        /**
         * 私钥解密过程
         *
         * @param privateKey
         *            私钥
         * @param cipherData
         *            密文数据
         * @return 明文
         * @throws Exception
         *             解密过程中的异常信息
         */
        public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
                throws Exception {
            if (privateKey == null) {
                throw new Exception("解密私钥为空, 请设置");
            }
            Cipher cipher = null;
            try {
                // 使用默认RSA
                cipher = Cipher.getInstance("RSA");
                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                byte[] output = cipher.doFinal(cipherData);
                return output;
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此解密算法");
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
                return null;
            } catch (InvalidKeyException e) {
                throw new Exception("解密私钥非法,请检查");
            } catch (IllegalBlockSizeException e) {
                throw new Exception("密文长度非法");
            } catch (BadPaddingException e) {
                throw new Exception("密文数据已损坏");
            }
        }
    
        /**
         * 公钥解密过程
         *
         * @param publicKey
         *            公钥
         * @param cipherData
         *            密文数据
         * @return 明文
         * @throws Exception
         *             解密过程中的异常信息
         */
        public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
                throws Exception {
            if (publicKey == null) {
                throw new Exception("解密公钥为空, 请设置");
            }
            Cipher cipher = null;
            try {
                // 使用默认RSA
                cipher = Cipher.getInstance("RSA");
                // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
                cipher.init(Cipher.DECRYPT_MODE, publicKey);
                byte[] output = cipher.doFinal(cipherData);
                return output;
            } catch (NoSuchAlgorithmException e) {
                throw new Exception("无此解密算法");
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
                return null;
            } catch (InvalidKeyException e) {
                throw new Exception("解密公钥非法,请检查");
            } catch (IllegalBlockSizeException e) {
                throw new Exception("密文长度非法");
            } catch (BadPaddingException e) {
                throw new Exception("密文数据已损坏");
            }
        }
    
        /**
         * 字节数据转十六进制字符串
         *
         * @param data
         *            输入数据
         * @return 十六进制内容
         */
        public static String byteArrayToString(byte[] data) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < data.length; i++) {
                // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
                stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
                // 取出字节的低四位 作为索引得到相应的十六进制标识符
                stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
                if (i < data.length - 1) {
                    stringBuilder.append(' ');
                }
            }
            return stringBuilder.toString();
        }
    
    
    
        public static void main(String[] args) throws Exception {
            String filepath="F:/temp/";
            File file=new File(filepath);
            if(!file.exists()){
                file.mkdir();
            }
            genKeyPair(filepath);
            System.out.println("--------------公钥加密私钥解密过程-------------------");
            String plainText="1223333323:8783737321232:dewejj28i33e92hhsxxxx";
            //公钥加密过程
            byte[] cipherData=encrypt(loadPublicKeyByStr(loadPublicKeyByFile(filepath)),plainText.getBytes());
            String cipher=new String(Base64.getEncoder().encode(cipherData));
            //私钥解密过程
            byte[] res=decrypt(loadPrivateKeyByStr(loadPrivateKeyByFile(filepath)), Base64.getDecoder().decode(cipher));
            String restr=new String(res);
            System.out.println("原文:"+plainText);
            System.out.println("加密密文:"+cipher);
            System.out.println("解密:"+restr);
            System.out.println();
        }
    }

    转载声明:本文转自方志朋,常见的安全算法

    展开全文
  • Java作为当今最广泛使用的开发平台,提供了完善的安全加密可扩展平台,为应用程序提供了从消息摘要,数字签名到复杂加密算法的支持。其中,Java加密架构(Java Cryptographic Architecture),简称JCA作为Java可扩展...
  • Android安全加密:Https编程

    千次阅读 2016-09-10 14:37:50
    概述SSL(Secure Sockets Layer 安全套接层),为网景公司(Netscape)所研发,用以保障在Internet 上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。一般通用之规格...

    Android安全加密专题文章索引

    1. Android安全加密:对称加密
    2. Android安全加密:非对称加密
    3. Android安全加密:消息摘要Message Digest
    4. Android安全加密:数字签名和数字证书
    5. Android安全加密:Https编程

    概述

    SSL(Secure Sockets Layer 安全套接层),为网景公司(Netscape)所研发,用以保障在Internet 上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。一般通用之规格为40 bit 之安全标准,美国则已推出128 bit 之更高安全标准,但限制出境。只要3.0 版本以上之I.E.或Netscape 浏览器即可支持SSL。

    TLS(Transport Layer Security 传输层安全),用于在两个通信应用程序之间提供保密性和数据完整性。TLS 是SSL 的标准化后的产物,有1.0 ,1.1 ,1.2 三个版本,默认使用1.0。TLS1.0 和SSL3.0 几乎没
    有区别,事实上我们现在用的都是TLS,但因为历史上习惯了SSL 这个称呼。

    SSL 通信简单图示:

    这里写图片描述

    SSL 通信详细图示:

    这里写图片描述

    当请求使用自签名证书的网站数据时,例如请求12306 的客运服务页面:https://kyfw.12306.cn/otn/,则会报下面的错误,原因是客户端的根认证机构不能识别该证书错误信息:unable to find valid certification path to requested target

    解决方案1

    一个证书可不可信,是由TrustManager 决定的,所以我们只需要自定义一个什么都不做的TrustManager即可,服务器出示的所有证书都不做校验,一律放行。

    public static void main(String[] args) throws Exception {
    //协议传输层安全TLS(transport layer secure)
    SSLContext sslContext = SSLContext.getInstance("TLS");
    //创建信任管理器(TrustManager 负责校验证书是否可信)
    TrustManager[] tm = new TrustManager[]{new EmptyX509TrustManager()};
    //使用自定义的信任管理器初始化SSL 上下文对象
    sslContext.init(null, tm, null);
    //设置全局的SSLSocketFactory 工厂(对所有ssl 链接都产生影响)
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    
     //URL url = new URL("https://www.baidu.com");
     URL url = new URL("https://kyfw.12306.cn/otn/");
     HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
     InputStream in = conn.getInputStream();
     System.out.println(Util.inputstream2String(in));
     }
    
     /**
     * 自定义一个什么都不做的信任管理器,所有证书都不做校验,一律放行
     */
     private static class EmptyX509TrustManager implements X509TrustManager{
     @Override
     public void checkClientTrusted(X509Certificate[] chain, String authType)
     throws CertificateException {
     }
    
     @Override
     public void checkServerTrusted(X509Certificate[] chain, String authType)
     throws CertificateException {
     }
    
     @Override
     public X509Certificate[] getAcceptedIssuers() {
     return null;
     }
    }

    解决方案2

    12306 服务器出示的证书是中铁集团SRCA 给他颁发的,所以SRCA 的证书是能够识别12306 的证书的,所以只需要把SRCA 证书导入系统的KeyStore 里,之后交给TrustManagerFactory 进行初始化,则可把SRCA 添加至根证书认证机构,之后校验的时候,SRCA 对12306 证书校验时就能通过认证。

    这种解决方案有两种使用方式:一是直接使用SRCA.cer 文件,二是使用改文件的RFC 格式数据,将其写在代码里。

    //12306 证书的RFC 格式(注意要记得手动添加两个换行符)
     private static final String CERT_12306_RFC = "-----BEGIN CERTIFICATE-----\n"+
    "MIICmjCCAgOgAwIBAgIIbyZr5/jKH6QwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ04xKTAn"+
    "BgNVBAoTIFNpbm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMB4X"+
    "DTA5MDUyNTA2NTYwMFoXDTI5MDUyMDA2NTYwMFowRzELMAkGA1UEBhMCQ04xKTAnBgNVBAoTIFNp"+
    "bm9yYWlsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRTUkNBMIGfMA0GCSqGSIb3"+
    "DQEBAQUAA4GNADCBiQKBgQDMpbNeb34p0GvLkZ6t72/OOba4mX2K/eZRWFfnuk8e5jKDH+9BgCb2"+
    "9bSotqPqTbxXWPxIOz8EjyUO3bfR5pQ8ovNTOlks2rS5BdMhoi4sUjCKi5ELiqtyww/XgY5iFqv6"+
    "D4Pw9QvOUcdRVSbPWo1DwMmH75It6pk/rARIFHEjWwIDAQABo4GOMIGLMB8GA1UdIwQYMBaAFHle"+
    "tne34lKDQ+3HUYhMY4UsAENYMAwGA1UdEwQFMAMBAf8wLgYDVR0fBCcwJTAjoCGgH4YdaHR0cDov"+
    "LzE5Mi4xNjguOS4xNDkvY3JsMS5jcmwwCwYDVR0PBAQDAgH+MB0GA1UdDgQWBBR5XrZ3t+JSg0Pt"+
    "x1GITGOFLABDWDANBgkqhkiG9w0BAQUFAAOBgQDGrAm2U/of1LbOnG2bnnQtgcVaBXiVJF8LKPaV"+
    "23XQ96HU8xfgSZMJS6U00WHAI7zp0q208RSUft9wDq9ee///VOhzR6Tebg9QfyPSohkBrhXQenvQ"+ 
    "og555S+C3eJAAVeNCTeMS3N/M5hzBRJAoffn3qoYdAO1Q8bTguOi+2849A=="+ 
    "-----END CERTIFICATE-----\n";
     public static void main(String[] args) throws Exception {
     // 使用传输层安全协议TLS(transport layer secure)
     SSLContext sslContext = SSLContext.getInstance("TLS");
     //使用SRCA.cer 文件的形式
    
    //FileInputStream certInputStream = new FileInputStream(new File("srca.cer"));
    //也可以通过RFC 字符串的形式使用证书
    ByteArrayInputStream certInputStream = new
    ByteArrayInputStream(CERT_12306_RFC.getBytes());
    // 初始化keyStore,用来导入证书
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    //参数null 表示使用系统默认keystore,也可使用其他keystore(需事先将srca.cer 证书导入
    keystore 里)
    keyStore.load(null);
    //通过流创建一个证书
    Certificate certificate = CertificateFactory.getInstance("X.509")
    .generateCertificate(certInputStream);
    // 把srca.cer 这个证书导入到KeyStore 里,别名叫做srca
    keyStore.setCertificateEntry("srca", certificate);
    // 设置使用keyStore 去进行证书校验
    TrustManagerFactory trustManagerFactory = TrustManagerFactory
    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    //用我们设定好的TrustManager 去做ssl 通信协议校验,即证书校验
    sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
    .getSocketFactory());
    URL url = new URL("https://kyfw.12306.cn/otn/");
    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
    InputStream in = conn.getInputStream();
    System.out.println(Util.inputstream2String(in));
    }

    Android 里的https 请求:

    把scra.cer 文件考到assets 或raw 目录下,或者直接使用证书的RFC 格式,接下来的做法和java工程代码一样

    //ByteArrayInputStream in = new ByteArrayInputStream("rfc".getBytes());
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    InputStream caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));
    Certificate ca;
    try {
        ca = cf.generateCertificate(caInput);
        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);
    
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);
    
    SSLContext context = SSLContext.getInstance("TLS");
    context.init(null, tmf.getTrustManagers(), null);
    
    URL url = new URL("https://certs.cac.washington.edu/CAtest/");
    HttpsURLConnection urlConnection =
            (HttpsURLConnection)url.openConnection();
    urlConnection.setSSLSocketFactory(context.getSocketFactory());
    InputStream in = urlConnection.getInputStream();
    copyInputStreamToOutputStream(in, System.out);
    

    双向证书验证

    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null);
    
    SSLContext sslContext = SSLContext.getInstance("TLS");
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.
            getInstance(TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    
    //初始化keystore
    KeyStore clientKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    clientKeyStore.load(getAssets().open("client.bks"), "123456".toCharArray());
    
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(clientKeyStore, "123456".toCharArray());
    
    sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
    

    Nogotofail

    网络流量安全测试工具,Google的开源项目:https://github.com/google/nogotofail

    Android安全加密专题总结

    以上学习所有内容,对称加密、非对称加密、消息摘要、数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识。数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制。最终才能在SSL 开发过程中得心应手。

    另外,对称加密和消息摘要这两个知识点是可以单独拿来使用的。

    数字证书使用到了以上学习的所有知识

    • 对称加密与非对称加密结合使用实现了秘钥交换,之后通信双方使用该秘钥进行对称加密通信。
    • 消息摘要与非对称加密实现了数字签名,根证书机构对目标证书进行签名,在校验的时候,根证书用公钥对其进行校验。若校验成功,则说明该证书是受信任的。
    • Keytool 工具可以创建证书,之后交给根证书机构认证后直接使用自签名证书,还可以输出证书的RFC格式信息等。
    • 数字签名技术实现了身份认证与数据完整性保证。
    • 加密技术保证了数据的保密性,消息摘要算法保证了数据的完整性,对称加密的高效保证了数据处理的可靠性,数字签名技术保证了操作的不可否认性。

    通过以上内容的学习,我们要能掌握以下知识点:

    • 基础知识:bit 位、字节、字符、字符编码、进制转换、io
    • 知道怎样在实际开发里怎样使用对称加密解决问题
    • 知道对称加密、非对称加密、消息摘要、数字签名、数字证书是为了解决什么问题而出现的
    • 了解SSL 通讯流程
    • 实际开发里怎样请求Https 的接口

    Android视频教程

    展开全文
  • tcp/ip网络通讯安全加密方法

    千次阅读 2018-04-06 08:35:21
    tcp/ip网络通讯安全是一个广受关注的话题,现在也有一些基于tcp/ip加密技术标准如SSL,TLS等。但很多时候编写一些简单的网络通讯把这标准加密应用添加进来乎一下子把程序变得复杂了,而实现自己的加密算法那就更加不...

    tcp/ip网络通讯安全是一个广受关注的话题,现在也有一些基于tcp/ip加密技术标准如SSL,TLS等。但很多时候编写一些简单的网络通讯把这标准加密应用添加进来乎一下子把程序变得复杂了,而实现自己的加密算法那就更加不可取;其实通过一些现有的加密的技术应用完全可以实现即简单又安全的网络通讯程序。首先保证网络通讯安全有两个方面,第一保证连接的有效性,其二就是保证内容即使被人拦截也难以从内容得到相关信息。

    连接有效性

    平常写网络程序在允许一个连接接入操作的时候,我们一般要对它进行一个有效性验证,如提供用户名密码或签名。

    签名:

    通过用户提供一分数据和数据相关签名信息,对方进行一个有效性验证。那这个数据和签名数据怎么做呢,其实现有加密技术中已经有一种描述提供了这种解决方案那就是RSA(非对称加密)。可以通过 RSA 的持有privatekey和publickey方进行一个数据签名,对方通过publickey进行一个验证.如果publickey和privatekey是配对的情况,那持有publickey就能验证成功,否则就会验证失败。在连接进行操作前可以通过这种方式进行处理,签名有效允许连接操作,无效的话可以直接把连接关闭。

    下面介绍通过c#如何实现这种签名:

    1
    2
    3
    4
    5
    6
    RasCrypto pri = new  RasCrypto();
    RasCrypto pub = new  RasCrypto();
    pub.PublicKey = pri.PublicKey;
    string  name = "henry" ;
    string  singdata = pri.Sign(name);
    Console.WriteLine(pub.Verify(name, singdata));

    RasCrypto是通过封装的类,源代码可以通过https://smarkdata.svn.codeplex.com/svn/Smark/Smark.Core/Smark.Core/RasCrypto.cs获取;在实际使用中最好是根据不同签名有不同的密对,这样即使某签名的密对被盗也不会影响其他用户的安全。

    用户名密码:

    基于用户名和密码验证是一种很常见的方式,但有个问题就是如何保证用户名和密码在通讯过程即使被截取了也难以得到用户名和密码呢?其实通过 RSA 也能够很好地解决这一问题。 RSA 提供public key加密而private key解密的方式,可以把public key提供给请求方就行了,private key保存在服务端;这样就可以保证加密的东西只有服务端才有解密,即使加密信息被其他人拦截也难以获取原有信息。

    下面介绍通过c#使用ras进行加解密

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    RasCrypto server = new  RasCrypto();
    RasCrypto client = new  RasCrypto();
    client.PublicKey = server.PublicKey;
    string  name = "henry" ;
    string  pwd = "123456" ;
    string  ename = client.Encrypt(name);
    string  epwd = client.Encrypt(pwd);
    string  dname = server.Decrypt(ename);
    string  dpwd = server.Decrypt(epwd);
    Console.WriteLine( "name:{0}" , name);
    Console.WriteLine( "pwd:{0}" , pwd);
    Console.WriteLine( "-----------------------------------------------------------" );
    Console.WriteLine( "ename:{0}" , ename);
    Console.WriteLine( "epwd:{0}" , epwd);
    Console.WriteLine( "-----------------------------------------------------------" );
    Console.WriteLine( "dname:{0}" , dname);
    Console.WriteLine( "dpwd:{0}" , dpwd);
    Console.WriteLine( "-----------------------------------------------------------" );

     

    为了应用更安全,针对不同的连接生成不同的RSA密对,这样就能保证每个连接的各自安全性.

    信息加密

    前面提到的 RSA 可以进行数据加解密,其安全性也非常可靠;但有个缺点就是RSA对数据比多的时候加密比较慢,有些 RSA 加密的实现还有数据长度的限制。所以在很多情况下就要选择别的加密方式,这里介绍DES(对称加密)。不过对称加密有个缺点就是密对双方都必须一样,这样就会导致一个问题就从某一方获取密对就能对数据加密和解密工作。所以对称加的密对保护就显示非常重要的,这个工作可以交给 RSA 来做。

    以下是c#运用 RSA +DES的加解密方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    RasCrypto server = new  RasCrypto();
      RasCrypto client = new  RasCrypto();
      client.PublicKey = server.PublicKey;
      DESCrypto serverdes = new  DESCrypto();
      DESCrypto clientdes = new  DESCrypto();
      //获取没加密的key,iv
      DESCrypto.DESInfo info = clientdes.KeyInfo;
      Console.WriteLine( "KEY: " +Smark.Core.Functions.ToString(info.Key));
      Console.WriteLine( "IV: " +Smark.Core.Functions.ToString(info.IV));
      Console.WriteLine( "" );
      //设置相应的RSA信息
      serverdes.PrivateRas = server;
      clientdes.PublicRas = client;
      //获取了设置RSA信息的key,iv
      info = clientdes.KeyInfo;
      Console.WriteLine( "KEY: "  + Smark.Core.Functions.ToString(info.Key));
      Console.WriteLine( "IV: "  + Smark.Core.Functions.ToString(info.IV));
      //数据加密
      serverdes.KeyInfo = info;
      string  value = "henryfan@msn.com" , evalue = null , dvalue = null ;
      evalue = serverdes.Encrypt(value);
      dvalue = clientdes.Decrypt(evalue);
      Console.WriteLine( "VALUE: "  + value);
      Console.WriteLine( "EVALUE: "  + evalue);
      Console.WriteLine( "DVALUE: "  + dvalue);
      Console.WriteLine( "" );
      evalue = clientdes.Encrypt(value);
      dvalue = serverdes.Decrypt(evalue);
      Console.WriteLine( "VALUE: "  + value);
      Console.WriteLine( "EVALUE: "  + evalue);
      Console.WriteLine( "DVALUE: "  + dvalue);
      Console.WriteLine( "" );
      Console.Read();

        通过RSA和DES就能够简单地实现可靠的网络通讯安全,不过有些朋友喜欢构建自己的加密方法,在这里并不见意这样做;因为自己构建的加密方法的可靠性并没有得到验证,并不像现有的加密方法经过长时候实践和大量的应用总结出来。

    相关资料:

    DES http://zh.wikipedia.org/wiki/%E8%B3%87%E6%96%99%E5%8A%A0%E5%AF%86%E6%A8%99%E6%BA%96 

    RSA http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

    展开全文
  • 上一篇介绍了SD卡底层驱动程序的调试手段和时序过程,适合初学者学习,但是在汽车级的涉及安全的大型项目中就需要一些数据安全保护。现在介绍一下SD卡的保护与解除方面的知识点。 SD卡官方英文资料中(可在该链接中...
  • Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名和数字证书 Android安全加密:Https编程 一、数字签名1. ...
  • 源代码安全加密解决方案

    千次阅读 2015-04-09 11:03:14
    企业级源代码加密软件主要是解决软件开发企业在开发过程中的源代码安全问题,现将苏州某软件开发企业的源代码加密系统使用过程中的问题与解决方案分享出来,仅供相关企业在考虑源代码加密软件时参考。
  • 源代码安全加密系统通过B/S架构应用于企业内部进行安全数据管理,它采用只进不出开发逻辑,落地及加密的安全功能,客户端无信任基本原则对企业内部数据从源头进行安全防护。对于开发企业的机密源代码来讲,在企业内...
  • cookie安全加密

    万次阅读 2016-07-25 11:39:55
    本文为对cookie安全加密的一些个人看法,仅作记录,大家有什么好的建议方法可以留言。cookie一般情况下用于记录用户登录状态的,比如userid,千万不要记录密码,由于cookie是存储在客户端的,所以cookie很容易被人...
  • Android安全加密:对称加密

    万次阅读 多人点赞 2016-09-09 22:46:57
    Android安全加密专题文章索引 Android安全加密:对称加密 Android安全加密:非对称加密 Android安全加密:消息摘要Message Digest Android安全加密:数字签名和数字证书 Android安全加密:Https编程 以上学习所有...
  • 网站的安全加密

    千次阅读 2017-02-21 09:47:23
    最近做一个小功能,能控制网站的运营时间限制、某些数据表的数据量、也防止...1、首先注册中由各种加密信息,这些信息的真是数据要有存储。我先做了一个企业信息管理的后台,把企业的基本信息和配置信息(我这里是限
  • 此方式会存在很严重的安全性问题,没有进行任何的验证,大家都可以通过这个方法获取到信息,导致数据泄露,并有可能会被篡改数据,造成更严重的问题。那么如何验证调用者身份并防止参数被篡改呢? 二、使用MD5进行...
  • 信息安全加密技术--凯撒密码

    千次阅读 2016-05-07 21:44:23
    凯撒密码技术是一种代替技术... 1、加密公式:  密文=(明文+位移数K)Mod26  即明文中每个字母用此字母表中后面第K个字符替代  2、解密共识:  明文=(密文-位移数K)Mod26  3、破解方式:  可利用电脑方便的列
  • 安全加密技术】非对称加密

    千次阅读 2015-07-08 23:35:11
    假如现在 你向支付宝 转账,即一些数据信息,为了保证信息传送的保密性、真实性、完整性和不可否认性,需要对传送的信息进行数字加密和签名,其传送过程为: 1.首先你要确认是否是支付宝的数字证书,如果确认为...
  • 安全加密技术】 对称加密

    千次阅读 2015-07-09 22:28:36
     上篇了解了《非对称加密》后 今天我来继续了解下加密技术中对称... 对称加密是最传统的加密方式,比上非对称加密,缺少安全性,但是它依旧是用的比较多的加密方法。  对称加密采用单密钥加密方式,不论是加密还是
  • 网络安全加密技术

    千次阅读 2018-01-25 11:18:41
    二 、常见的加密算法  1. base64  Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法!也是MIME...
  • 通过漫画的形式由浅入深带你读懂htts是如何保证一台主机把数据安全发给另一台主机的 对称加密 一禅:在每次发送真实数据之前,服务器先生成一把密钥,然后先把密钥传输给客户端。之后服务器给客户端...
  • 安全加密算法

    千次阅读 2021-03-24 14:32:15
    安全加密算法 SKIPJACK\RC4\RSA(1024位以下) des、md2、md4、md5
  • 数据安全及各种加密算法对比

    千次阅读 2018-06-22 11:55:40
    然而市场上存在着各种各样的抓包工具及解密算法,甚至一些公司有专门的逆向部门,这就加大了数据安全的风险,本文将通过以下几个方面对各种加密算法进行分析对比:Base64编码(基础)单项散列函数 MD5、SHA1、SHA256...
  • 信息安全加密技术---维吉尼亚密码

    千次阅读 2016-05-08 06:43:43
    人们在单一恺撒密码的基础上扩展出多表密码,称为“维吉尼亚”密码。是法国密码学家维吉尼亚在1586年提出的...  1、加密公式:密文=(明文+密钥)Mod26-1  2、解密公式:明文=[26+(密文-密钥)]Mod26+1  例如...
  • 结合二维压缩感知和混沌映射的双图像视觉安全加密算法 摘要 为解决图像加密技术在安全性和效率上的均衡问题,提出了一种结合压缩感知和混沌映射的双图像视觉安全加密算法。首先,通过引入非线性反馈项对经典一维...
  • 网络安全几种加密方式

    万次阅读 2018-11-01 18:07:26
    缺点:不具备安全性,可认证性 2.对称加密 适用场景:收发方数量固定,密钥使用对象少 缺点:BS网络传输关系,密钥过多难维护,除非对密钥进行加密传输 3.非对称加密 3.1接收方发送公钥(保证数据完整性) ...
  • Android安全加密:非对称加密

    千次阅读 2016-09-10 13:48:24
    介绍与对称加密算法不同,非对称加密算法需要两个密钥:公钥(publickey)和私钥(privatekey)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用...
  • java安全加密技术

    千次阅读 2016-08-02 18:02:17
    加密方式对称加密算法只有一个密钥key进行加密解密,可以逆向加解密。1.凯撒密码古代有名的加密算法,将加密的数据进行一定的以为,属于对称加密,密钥key = 2(int 值)。这种加密非常简单,只需要对相应的明文移位就...
  • 大数据与云计算笔记[二]:安全加密

    千次阅读 2016-10-15 19:42:24
    采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。 速度快,对称性加密通常在消息发送方需要加密大量数据时使用 所谓对称,就是采用...
  • 世界上迄今为止最安全加密算法

    千次阅读 2019-11-28 21:58:00
    全世界只有3.14 %的人关注了青少年数学之旅一个只能用算力来破解的加密算法1人类的加密史公元前5世纪,古希腊人使用一根叫scytale的棍子来传递加密信息。要加密时,先绕棍子卷一张纸...
  • FTP设置SSL安全加密

    万次阅读 2009-10-27 13:51:00
    一般的FTP服务器是以明文方式传输数据的,安全性极差,信息很容易被盗,虽然它提供了SSL加密功能,默认情况下也是没有启用的。所以说为了保证特殊环境下的数据安全,有必要启用SSL功能,提高服务器数据传输的安全性...
  • 智能安全加密芯片---ACL16

    千次阅读 2019-02-28 15:09:30
    近日来,印巴冲突持续进行,国际情势日趋紧张,和平,安全是永恒不变的话题,而在半导体行业里,安全加密芯片的导入为很多产品保驾护航,免遭攻击与击破,为行业发展带来了巨大贡献。今天为大家介绍一款安全加密芯片...
  • 安全测试之不安全加密存储

    千次阅读 2016-01-29 19:39:38
    安全加密存储,不仅局限于没有对密码等需要保护的字段进行加密之外,还包括加密算法太弱,很容易就可以破解。一、加密弱点 使用不安全加密算法。加密算法强度不够,一些加密算法甚至可以用穷举法破解。 加密...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 530,284
精华内容 212,113
关键字:

安全加密