推荐 最新
超超

哈希函数的理解

前言什么是哈希函数?它能用来干嘛?本文将以图文的形式讲解上述问题,欢迎各位感兴趣的开发者阅读本文。概念与作用哈希函数可以把给定的数据转换成固定长度的无规律数值。转换后的无规律数值可以作为数据摘要应用于各种各样的场景。图解示例我们可以把哈希函数想象成搅拌机,如下图所示。 将数据放进搅拌机里 经过哈希函数计算后,搅拌机会输出固定长度的无规律数值。输出的无规律数值就是“哈希值”。哈希值虽然是数字,但多用十六进制来表示。 计算机使用二进制管理所有数据,虽然哈希值是用十六进制表示的,但它也是数据,计算机在存储哈希值时,会通过计算将其转换为二进制进行管理。 哈希函数的特征哈希值的长度与输入数据的大小的无关 输入相同数据,输出的哈希值也必定相同 输入相似的数据,输出的哈希值必定不同。 输入的数据完全不同,但输出的哈希值可能是相同的。虽然这种情况的出现概率较低,这种情况就叫做“哈希冲突” 哈希值是不可逆的,通过哈希值不可能反向推算出原本的数据。 哈希函数的作用哈希函数的算法中具有代表性的是「MD5」、「SHA-1」、「SHA-2」等,其中SHA-2是现在应用较为广泛的一个,而MD5和SHA-1存在安全隐患,不推荐使用。不同算法计算方法不同,计算出来的哈希值也会有所不同。哈希函数的特征中有一条是输入的数据相同,输出的哈希值也必定相同,这个特征的前提是使用的是同一种算法。根据哈希函数的特征,我们可以将其应用到「数据库密码的保存」。如果把密码直接保存到服务器,可能会被「第三者窃听」,因此要算出密码的哈希值,并只存储哈希值。当用户输入密码时,先算出该密码的哈希值,再把它和服务器中的哈希值进行比对。这样一来,就算保存的哈希值暴露了,鉴于哈希函数“哈希值不可逆”的特征,第三者也无法得知原本的密码。就像这样,使用哈希函数可以更安全地实现基于密码的用户认证。

0
0
0
浏览量1468
摸鱼校尉

【ManageEngine】加强企业特权访问安全性的7个方法

在任何企业中,特权用户都可以不受任何限制的访问IT基础架构中广泛的关键任务系统和数据。尽管如今许多网络攻击都可以联系到这种无限访问的滥用(无论是由内部的恶意特权人员或或是外部的参与者),但是仍旧存在大量企业机构的安全程序采用脆弱、肤浅的特权控制措施。这也就是特权访问管理(PAM)所应发挥作用的地方。PAM是一组保护、控制及监控企业关键系统上特权活动和会话的策略,而不影响业务生产率。这里我们分享一些实用的技巧,帮助您设计、构建和开发一套强大的防御机制来防止滥用特权。1、创建对网络中所有特权访问的可见性发现并识别在IT基础架构中散布的所有特权账户、密钥、证书和敏感文档,将它们统一存放在一个中心位置。围绕谁可以访问它们,以及访问多长时间,来设置权限和策略。通过这种方式,构建对关键数据所有权访问的可见性和控制,尤其是针对长期被遗忘或废弃的特权账户,避免为恶意行为人员提供高风险的后门。2、为特权访问构建多层安全保护构建多因素认证来确认这些执行特权活动的人员身份信息。进一步的安全措施,设置审批流程,控制对关键系统的访问,并设定时间以自动回收和重置访问凭证。通过这种强访问控制过程,攻击者就很难蒙混过关,提升权限在网络中肆意破坏,阻止业务运营。3、采用更简便、快捷的工作流来提升业务生产力支持用户通过一条安全的路径来远程访问关键的系统,而无需修改防火墙策略、连接VPN或记录大量复杂的密码。使用单点登录,使用户能够在混合环境中自动登录远程系统和应用。此类做法能够防止未知源的恶意访问,同时加快操作速度、提升生产力、加快价值的实现时间。4、通过消除硬编码的凭证来进一步压缩攻击面在您的DevOps环境中识别缺省的、硬编码的凭证,将它们存放在统一的位置。并强制通过API以及自动化脚本来从中心密码库获取所需的凭证,防止高风险密码的泄露。实施密码安全的最佳实践,例如定期轮换密码、增强复杂度,以大幅减少凭证盗取攻击以及利用漏洞的机会。5、增强特权会话的监督和问责记录每个特权用户的会话,并将它们作为视频存在安全、加密的数据库中,以供将来审阅。利用影射特权会话,实时监控特权会话,以及时发现并制止可以会话,并有效调查有风险的会话。拥有对受信的内部特权人员,以及第三方供应商所发起的特权会话的完整、细粒度的记录,有助于轻松治理和更好的对特权会话活动追责。6、随时证明符合法规与安全策略在清晰明确、可下载的审计追踪和报告中,捕获所有涉及特权凭证和访问的事件。许多合规性标准与行业法规,如SOX、HIPAA和PCI DSS,都明确了追踪与监控所有对您的关键系统访问的要求。通过审计和合规性管理的中心联系点,您可以轻松向审计员以及法证调查员证明所有的安全控制措施都已到位。7、集成先进技术,制定更好的业务决策采用AI与机器学习驱动的监控能力,持续检测异常和可能有害的特权活动,并自动启动缓解控制以防止出现破坏。与SIEM和扫描工具的集成,有助于识别漏洞并及时出台治理措施。将ITSM纳入组合,简化特权访问的请求,提高变更和资产管理的效率。将特权访问数据与上述所有的功能关联和同步,并通过中心控制台编排他们的工作流程。这样,您可以在整个基础架构中实施特权访问安全,获得增强的态势感知能力,减少组织孤岛。ManageEngine PAM360是一个综合的特权访问管理解决方案,可支持企业针对其整个IT基础架构中的用户、系统及应用的管理访问和权限,实施严格的控制和治理。ManageEngine PAM360有助于现代企业应对不断变化的PAM需求,已连续两年入选Gartner 特权访问管理魔力象限。

1
0
0
浏览量2030
超超

数据传输过程中可能遇到的安全问题以及解决方案

前言客户端与服务端进行数据交互时,会有哪些安全问题产生?这些问题应如何解决?本文将以图文的形式讲解上述问题,欢迎各位感兴趣的开发者阅读本文。传输数据时的四个问题在互联网中传输数据时,可能会遭到中间人的攻击,从而拦截数据、伪造数据,接下来就跟大家分享下传输过程中可能发生的四个问题。窃听如下图所示,A向B发送的消息可能会在传输途中被X偷看,这就是窃听。 假冒如下图所示,A向B发送了消息,A以为B已经接收了消息,然后B有可能是X冒充的;反过来,B以为从A那里收到了消息,然后A也有可能是X冒充的。这种问题就叫作“假冒” 篡改A向B发送消息,B收到了A发送的消息,此时B收到的消息可能不是A的原话,如下图所示,在消息的传输途中,内容已经被X更改了。这种行为就叫做“篡改”。除了被第三者篡改外,通信故障导致的数据损坏也可能会使消息内容发生变化。 事后否认如图所示,B收到了A发送的消息,但A作为消息的发送者可能对B抱有恶意,并在事后声称“这不是我发送的消息”。这种情况会导致互联网上的商业交易或合同无法成立。这种行为便是“事后否认”。 用安全技术解决传输中的问题加密技术我们会使用传输内容进行加密的手段,来解决第三者「窃听」的问题。 如下图所示,我们对传输中的数据进行加密,设置可以访问数据的Key,这个Key只有A和B知道,第三者拿到加密后的数据没有Key是无法查看的。 消息认证码与数字签名通常情况下,我们会使用消息认证码或者数字签名解决「假冒」、「篡改」、「事后否认」问题。如下图所示,我们设置一个消息认证码,这个消息码会根据发送数据的内容以及内容长度生成一个随机码和解开这个随机码的key,要查看消息时会通过key来验证,如果消息在传输途中被篡改了那么随机码就会变,使用key就无法解密,那么就很好的防止了上述问题。数字签名的原理与消息认证码的原理大致相同,也能够解决上述问题。

0
0
0
浏览量940
超超

共享密钥加密与公开密钥加密

前言加密数据的方法可以分为两种:加密和解密都使用相同密钥的“共享密钥加密”和分别使用不同密钥的“公开密钥加密”。本文将以图文的形式讲解这两种加密的机制以及相关问题,挑选使用最为广泛两种加密算法,用JAVA将其实现,欢迎各位感兴趣的开发者阅读本文。共享密钥加密概念共享密钥加密是加密和解密都是用相同密钥的一种加密方式,由于使用的密钥相同,所以这种算法也被称为“对称加密”,实现共享加密的算法有:「AES」、「DES」、「动态口令」等,其中AES的应用最为广泛。 处理流程图解例如,A准备通过互联网向B发送数据 由于有被窃听的风险,所以需要把数据加密后再发送。 A使用密钥加密数据,并将秘文发送给B。B收到秘文后,使用相同的密钥对其进行解密。这样B就取得了原本的数据。此时的数据已经是加密好的了,就不需要担心第三者窃取数据了,因为它没有密钥解开此密文。 可能产生的问题如图所示,B接收A发送的密文时,密文可能已经被X窃听了。此时,B不知道加密时使用的是什么密钥。 A需要通过某种手段将密钥交给B。和密文一样,A又在互联网上向B发送了密钥。 B使用收到的密钥对密文进行解密,但是该密钥也有可能会被X窃听,这样以来X也可以使用密钥对密文进行解密了。❝使用共享密钥加密时,如果接收方不知道密钥是什么,发送方就要通过互联网发送密钥给接收方,此时密钥可能会被第三者监听,这就是共享密钥加密最大问题的所在。❞解决方案如上所述,共享密钥加密存在密钥送达问题,想要解决这个问题,我们可以使用“密钥交换协议”和“公开密钥加密”两种方法。恩尼格玛密码机第二次世界大战中,德军所用的”恩尼格玛密码机“使用的加密方式就是共享密钥加密,我们熟知的英国数学家「艾伦·图灵」就破解了这个密码机生成的密文,在二战中为英国做了很多的贡献,比如著名的“诺曼底登陆”事件,昨晚看了一部电影《模仿游戏》,该电影讲了图灵的一生,其中就包括了破解恩尼格玛密码机这一部分,挺好的一部电影,感兴趣的朋友可以去看看。JAVA实现AES加密我们用Java实现下AES加密。创建AESUtils文件,编写AES加密工具类package com.lk.util; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.SecureRandom; public class AESUtils { /** * 密钥长度: 128, 192 or 256 */ private static final int KEY_SIZE = 128; /** * 加密/解密算法名称 */ private static final String ALGORITHM = "AES"; /** * 随机数生成器(RNG)算法名称 */ private static final String RNG_ALGORITHM = "SHA1PRNG"; /** * 生成密钥对象 * @param key byte[] 类型参数 * @return AES密钥对象 */ private static SecretKey generateKey(byte[] key) throws Exception { // 创建安全随机数生成器 SecureRandom random = SecureRandom.getInstance(RNG_ALGORITHM); // 设置 密钥key的字节数组 作为安全随机数生成器的种子 random.setSeed(key); // 创建 AES算法生成器 KeyGenerator gen = KeyGenerator.getInstance(ALGORITHM); // 初始化算法生成器 gen.init(KEY_SIZE, random); // 生成 AES密钥对象 return gen.generateKey(); } /** * 数据加密: 明文 -> 密文 */ public static byte[] encrypt(byte[] plainBytes, byte[] key) throws Exception { // 生成密钥对象 SecretKey secKey = generateKey(key); // 获取 AES 密码器 Cipher cipher = Cipher.getInstance(ALGORITHM); // 初始化密码器(加密模型) cipher.init(Cipher.ENCRYPT_MODE, secKey); // 加密数据, 返回密文 return cipher.doFinal(plainBytes); } /** * 数据解密: 密文 -> 明文 */ public static byte[] decrypt(byte[] cipherBytes, byte[] key) throws Exception { // 生成密钥对象 SecretKey secKey = generateKey(key); // 获取 AES 密码器 Cipher cipher = Cipher.getInstance(ALGORITHM); // 初始化密码器(解密模型) cipher.init(Cipher.DECRYPT_MODE, secKey); // 解密数据, 返回明文 return cipher.doFinal(cipherBytes); } /** * byte数组转16进制 * * @param bytes byte数组 * @return 返回16进制字符串 */ public static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte aByte : bytes) { String hex = Integer.toHexString(aByte & 0xFF); if (hex.length() < 2) { sb.append(0); } sb.append(hex); } return sb.toString(); } /** * 16进制转byte * @param inHex 16进制字符串 * @return byte */ public static byte hexToByte(String inHex) { return (byte) Integer.parseInt(inHex, 16); } /** * 16进制转byte数组 * @param inHex 16进制字符串 * @return byte数组 */ public static byte[] hexToByteArray(String inHex) { int hexlen = inHex.length(); byte[] result; if (hexlen % 2 == 1) { //奇数 hexlen++; result = new byte[(hexlen / 2)]; inHex = "0" + inHex; } else { //偶数 result = new byte[(hexlen / 2)]; } int j = 0; for (int i = 0; i < hexlen; i += 2) { result[j] = hexToByte(inHex.substring(i, i + 2)); j++; } return result; } /** * 加密文件: 明文输入 -> 密文输出 */ public static void encryptFile(File plainIn, File cipherOut, byte[] key) throws Exception { aesFile(plainIn, cipherOut, key, true); } /** * 解密文件: 密文输入 -> 明文输出 */ public static void decryptFile(File cipherIn, File plainOut, byte[] key) throws Exception { aesFile(plainOut, cipherIn, key, false); } /** * AES 加密/解密文件 */ private static void aesFile(File plainFile, File cipherFile, byte[] key, boolean isEncrypt) throws Exception { // 获取 AES 密码器 Cipher cipher = Cipher.getInstance(ALGORITHM); // 生成密钥对象 SecretKey secKey = generateKey(key); // 初始化密码器 cipher.init(isEncrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secKey); // 加密/解密数据 InputStream in = null; OutputStream out = null; try { if (isEncrypt) { // 加密: 明文文件为输入, 密文文件为输出 in = new FileInputStream(plainFile); out = new FileOutputStream(cipherFile); } else { // 解密: 密文文件为输入, 明文文件为输出 in = new FileInputStream(cipherFile); out = new FileOutputStream(plainFile); } byte[] buf = new byte[1024]; int len = -1; // 循环读取数据 加密/解密 while ((len = in.read(buf)) != -1) { out.write(cipher.update(buf, 0, len)); } out.write(cipher.doFinal()); // 最后需要收尾 out.flush(); } finally { close(in); close(out); } } private static void close(Closeable c) { if (c != null) { try { c.close(); } catch (IOException e) { // nothing } } } } 在main函数中测试工具类 public static void main(String[] args) throws Exception { // 原文内容 String content = "你好,我是要发送的数据"; // AES加密/解密用的原始密码 String key = "MagicalProgrammer"; // 加密数据, 返回密文 byte[] cipherBytes = AESUtils.encrypt(content.getBytes(), key.getBytes()); // byte[]转16进制 String cipherString = AESUtils.bytesToHex(cipherBytes); // 输出加密后的16进制密文 System.out.println("加密后的密文为: "); System.out.println(cipherString); // 解密数据, 返回明文 byte[] plainBytes = AESUtils.decrypt(AESUtils.hexToByteArray(cipherString), key.getBytes()); // 输出解密后的明文 System.out.println("解密后结果为: "); System.out.println(new String(plainBytes)); } 公开密钥加密概念公开密钥加密是加密和解密使用不同密钥的一种加密方法。由于使用的密钥不同,所以这种算法也被称为“非对称加密”。加密用的密钥叫做“公开密钥”,解密用的叫做“私有密钥”。处理流程图解如图所示,A通过互联网向B发送数据。 首先,由接收方B来生成公开密钥和私有密钥。 然后,将公开密钥发送给B。 A使用B发来的公开密钥加密数据 A将密文发送给B,B再使用私有密钥对密文进行解密。这样,B就得到了原本的数据。 公开密钥和密文都是通过互联网传输的,因此可能被X窃听。但是,使用公开密钥无法解密密文,因此X也无法得到原本的数据。❝实现公开密钥加密的算法有「RSA算法」、「椭圆曲线加密算法」等,其中使用最为广泛的是RSA算法。❞方便多人传输数据在和多人传输数据时,使用公开密钥加密十分方便。例如,B预先准备好了公开密钥和私有密钥, 公开密钥是不怕被人知道的,所以B可以把公开密钥发布在网上。 此时,有许多人都想向B发送数据。 首先,想发送数据的人需要从王山取得B发布的公开密钥。 然后,用获取到的公开密钥加密要发送的数据。 最后,把密文发送给B B用私有密钥对收到的密文进行解密,取得原本的数据。这种情况就不需要为每个发送对象都准备对应的密钥了。需要保密的私有密钥由接收方保管,所以安全性也更高。❝如果使用共享密钥加密,密钥的需求数量会随着发送人数的增多而急剧增多。例如,有2个人相互发送数据,需要2个密钥,但是5个人相互发送数据就需要10个密钥,100人就需要4950个。假设有n个人需要相互发送数据,那么需要的密钥数量就为「n(n-1)/2」。❞中间人攻击公开密钥加密存在公开密钥可靠性的问题,B在给A发送公开密钥时,可能会被第三者拦截到这个公开密钥,第三者拿到公开密钥后,保存到本地,自己重新生成一个新的公开密钥发送给A,A使用第三者的公开密钥加密数据后,将数据发送给A时,第三者劫持A发送的数据,用自己的私有密钥解密数据,此时第三者就拿到了B要发送的数据,然后第三者用B的公开密钥再次对解密的数据进行加密,然后发送给B,B用自己的私有密钥正常解开了B发送的数据,整个发送与接收的过程中,没有发生任何问题,因此A也察觉不到数据已经泄漏,这种通过中途替换公开密钥来窃听数据的攻击方法就叫做「中间人攻击」。我们回到B生成公开密钥和私有密钥的时候,我们用PB表示公开密钥,SB表示私有密钥。 X想要窃听A发送给B的数据,于是他准备了公开密钥PX和私有密钥SX。 在B把公开密钥PB发送给A的时候 X把公开密钥PB替换成自己的PX 于是公开密钥Px传到了A那里,由于公开密钥无法显示自己是由谁生成的,所以A不会发现自己收到的公开密钥已经被人替换。 A使用公开密钥PX对数据加密 当A把想要给B的密文发送出去后,X接收了这个密文。 这个密文由X生成的公开密钥PX加密而成,所以X可以用自己的私有密钥SX对密文进行解密。 X用B生成的公开密钥PB加密数据 X把密文发送给B,这个密文由B发出的公开密钥PB加密而成,所以B可以用自己的私有密钥SB来解密,从收到密文到解密密文都没发生任何问题,因此B也不可能意识到自己已经被窃听。 解决方案公开密钥的可靠性会出现问题,因此A无法判断收到的公开密钥是否来自B,要想解决这一问题,就要用到“数字证书。公开密钥加密还有一个问题,加密和解密都比较耗时。所以这种方式不适用于持续发送零碎数据的情况,要想解决这一问题,就要用到“混合加密”。实现难点要想找到实现公开密钥加密的算法并不容易。考虑到加密所需的计算流程,算法必 须满足如下条件。可以使用某个数值对数据进行加密使用另一个数值对加密数据进行计算就可以让数据恢复原样。无法从一种密钥推算出另一种密钥。稍微思考一下便知道,想要找到满足以上条件的算法难度有多大。所以,RSA 等可 以实现公开密钥加密的算法的提出,对当今互联网社会的安全有着重要的意义。JAVA实现RSA加密我们用Java实现下RSA加密创建RSAUtils文件,编写RSA加密工具类package com.lk.util; import java.util.Base64; import javax.crypto.Cipher; 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.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * RSA加密工具类 */ public class RSAUtils { /** * 密钥长度 于原文长度对应 以及越长速度越慢 */ private final static int KEY_SIZE = 1024; /** * 用于封装随机产生的公钥与私钥 */ private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); /** * 随机生成密钥对 */ public static Map genKeyPair() throws NoSuchAlgorithmException { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器 keyPairGen.initialize(KEY_SIZE, new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded()); // 得到私钥字符串 String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded()); // 将公钥和私钥保存到Map //0表示公钥 keyMap.put(0, publicKeyString); //1表示私钥 keyMap.put(1, privateKeyString); return keyMap; } /** * RSA公钥加密 * * @param str 加密字符串 * @param publicKey 公钥 * @return 密文 * @throws Exception 加密过程中的异常信息 */ public static String encrypt(String str, String publicKey) throws Exception { //base64编码的公钥 byte[] decoded = Base64.getDecoder().decode(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); String outStr = Base64.getEncoder().encodeToString(cipher.doFinal(str.getBytes("UTF-8"))); return outStr; } /** * RSA私钥解密 * * @param str 加密字符串 * @param privateKey 私钥 * @return 明文 * @throws Exception 解密过程中的异常信息 */ public static String decrypt(String str, String privateKey) throws Exception { //64位解码加密后的字符串 byte[] inputByte = Base64.getDecoder().decode(str); //base64编码的私钥 byte[] decoded = Base64.getDecoder().decode(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); String outStr = new String(cipher.doFinal(inputByte)); return outStr; } } 在main函数中测试工具类public static void main(String[] args) throws Exception { // 随机生成的密钥和公钥 Map<Integer, String> keyMap = new HashMap<Integer, String>(); //生成公钥和私钥 keyMap = RSAUtils.genKeyPair(); System.out.println("公钥:" + keyMap.get(0)); System.out.println("私钥:" + keyMap.get(1)); // 要加密的数据 String message = "你好,我是通过RSA加密的数据"; // 使用公钥加密 String messageEn = RSAUtils.encrypt(message, keyMap.get(0)); System.out.println("密文:" + messageEn); // 使用私钥解密 String messageDe = RSAUtils.decrypt(messageEn, keyMap.get(1)); System.out.println("解密:" + messageDe); }

0
0
0
浏览量661
超超

迪菲赫尔曼密钥交换的理解

前言迪菲赫尔曼密钥交换是一种可以在通信双方之间安全交换密钥的方法。这种方法通过将双方共有的密码数值隐藏在公开数值相关的运算中,来实现双方之间密钥的安全交换。概念图解假设有一种方法可以合并这两个密钥。使用这种方法来合并密钥P和密钥S,就会得到由这两个密钥的成分所构成的密钥P-S。 这种合成方法有三个特征。第一,即将持有密钥P和合成的密钥P-S,也无法把密钥S单独取出来。 第二,不管是怎样合成而来的密钥,都可以把它作为新的元素,继续与别的密钥合并而成。如图所示,使用密钥P和密钥P-S,还能合成出新的密钥P-P-S。 第三,密钥的合成结果与合成顺序无关,只与用了哪些密钥有关。比如合成密钥B和密钥C后,得到的密钥B-C,再将其与密钥A合成,得到的就是密钥A-B-C。而合成密钥A和密钥C后,得到的是密钥A-C,再将其与密钥B合成,得到的就是密钥B-A-C。此处的密钥A-B-C和密钥B-A-C是一样的 图解示例如图所示,用上述方法,在A和B这两人之间安全的交换密钥。首先由A生成密钥P。 然后A把密钥P发送给B。 接下来,A和B各自准备自己的私有密钥SA和SB。 A利用密钥P和私有密钥SA合成新的密钥P-SA。 B也利用密钥P和私有密钥SB合成新的密钥P-SB。 A将密钥P-SA发送给B,B也将密钥P-SB发送给A。A将私有密钥SA和收到的密钥P-SB合成为新的密钥SA-P-SB。 同样地,B也将私有密钥SB和收到的密钥P-SA合成为新的密钥P-SA-SB。于是A和B都得到了P-SA-SB。这个密钥将作为“加密密钥”和“解密密钥”来使用。 安全性图解接下来,我们验证下该密钥交换的安全性。因为密钥P、密钥P-SA和密钥P-SB需要在互联网上进行传输,所以有可能会被X窃听。 但是,X无法用自己窃听道的密钥合成出P-SA-SB,因此这种交换方式是安全的。 迪菲赫尔曼密钥交换图解如图所示,P、G两个整数表示一开始生成的公开密钥P。其中P是一个非常大的素数,而G是素数P所对应的生成元(或者“原根”)中的一个。 首先,由A来准备素数P和生成元G。这两个数公开也没有关系。 A将素数P和生成元G发送给B。 接下来,A和B分别准备了各自的秘密数字X和Y。X和Y都必须小于p-2 A和B分别计算"(G的秘密数字次方)mod P"。mod运算就是取余运算。"G mod P"就是计算G除以P后的余数。此处的运算等同于概念意义上的"合成"。A和B将自己的计算结果发送给对方。 A和B收到对方的计算结果后,先计算这个值的秘密数字次方,然后再mod P。最后A和B会得到相同的结果。 安全性如图所示,即便X窃听了整个通信过程,也无法使用窃听到的数字计算出A和B共有的数字。而且,X也无法计算出保密数字X和Y。因此,此处使用迪菲赫尔曼密钥交换是安全的。 迪菲赫尔曼密钥交换是通过素数P、生成元G和“G的x次方 mod P”求出X的问题就是「离散对数问题」,至今为止尚未找到这个问题的解法,而迪菲赫尔曼密钥交换正是利用了这个数学难题,因此在离散对数问题未解决前,该加密方法就是安全的。❝使用迪菲赫尔曼密钥交换,通信双方仅通过交换一些公开信息就可以实现密钥交换。但实际上,双方并没有交换密钥,而是生成了密钥。因此,该方法又被叫做「迪菲赫尔曼协议」。❞

0
0
0
浏览量590
超超

混合加密的理解

前言共享密钥加密存在无法传输安全密钥的密钥分配问题,公开密钥加密又存在加密解密速度比较慢的问题。结合这两种方法可以实现互补的一种方法「混合加密」,本文将以图文的形式讲解混合加密的处理流程,欢迎各位感兴趣的开发者阅读本文。概念传输密钥时使用公开密钥加密,传输数据时使用共享密钥加密,这种方式就叫做「混合加密」。 处理流程图解假设A准备通过互联网向B发送数据,使用处理速度比较快的共享密钥加密对数据进行加密。加密时所用的密钥在解密时也要用到,因此A需要把密钥发送给B。 将密钥通过公开密钥进行加密后,A就可以将其安全地发送给B了。因此,作为接收方,B需要事先生成公开密钥P和私有密钥S。 B将公开密钥发送给A A使用收到的公开密钥,对共享密钥加密中需要使用的密钥进行加密。 A将加密后的密钥发送给B。 B使用私有密钥对密钥进行解密这样,A就把共享密钥加密中使用的密钥安全地发送给了B。 接下来,A只要将使用这个密钥加密好的数据发送给B即可。加密数据时使用的是处理速度较快的共享密钥加密。

0
0
0
浏览量597
超超

数字证书的理解

前言「公开密钥加密」和「数字签名」无法保证公开密钥确实来自信息的发送者。因此,就算公开密钥被第三者恶意替换,接收方也不会注意到。数字证书可以完美的解决这一问题,保证公开密钥的正确性。处理流程图解A持有公开密钥PA和私有秘钥SA,现在想要将公开密钥PA发送给B。 首先,A需要向认证中心申请发行证书,证明公开密钥PA确实由自己生成。 认证中心里保管者他们自己准备的公开密钥PC和私有秘钥SC。 A将公开秘钥PA和包含邮箱信息的个人资料发送给认证中心。 认证中心对收到的资料进行确认,判断其是否为A本人的资料。确认完毕后,认证中心使用自己的私有秘钥SC,根据A的资料生成数字签名。 认证中心将生成的数字签名和资料放进同一个文件中。 然后,把这个文件发送给A A的数字证书如下 A将作为公开密钥的数字证书发送给了B。 B收到数字证书后,确认证书里的邮件地址确实是A的地址。接着,B获取了认证中心的公开密钥。 B对证书内的签名进行验证,判断它是否为认证中心给出的签名。证书中的签名只能用认证中心的公开密钥PC进行验证。如果验证结果没有异常,就能说明这份证书的确由认证中心发型。 B确认了证书是由认证中心发行的,且邮件地址就是A的之后,B从证书中取出A的公开密钥PA。这样,公开密钥便从A传到了B。 数字证书的安全性假设X冒充A,准备向B发送公开密钥PX。 但是,B没有必要信任以非证书形式收到的公开密钥。 假设X为了假冒A,准备在认证中心登记自己的公开密钥。然后X无法使用A的邮箱地址,因此无法获得A的证书。 原理解析通过数字证书,信息的接收者可以确认公开密钥的制作者。B得到了认证中心的公开密钥,就一定来自认证中心吗?由于公开密钥自身不能表示其制作者,所以有可能是冒充认证中的X所生成的。也就是说,这样同样存在公开密钥问题。 实际上,认证中心的公开密钥PC是以数字证书的形式交付的,会有更高级别的认证中心对这个认证中心署名。 例如,下图的树结构,上面的认证中心为下面的认证中心发行证书。那么,这个树结构是怎么生成的,假设存在一个被社会广泛认可的认证中心A。此时出现了一个刚成立的公司B,虽然B想要开展认证中心的业务,但它无法得到社会的认可。于是,B向A申请发行数字证书。当然A会对B能否开展认证中心业务进行适当检测,只要A发行了证书,公司B就可以向社会表示自己获得了公司A的信任。于是,通过大型组织对小组织的信赖担保,树结构就建立了起来。最顶端的认证中心被称为“根认证中心”,其自身的正当性由自己证明。对根认证中心自身进行证明的证书为“根证书”。如果根证书不被信任,整个组织就无法运转。因此根认证中心多为大型企业,或者与政府关联且已经取得了社会信赖的组织。 数字证书在网站中的运用上面讲述的是个人之间交付公开密钥的例子,在网站之间的通信也要用到数字证书。只要能收到来自网站的含有公开密钥的证书,就能确认该网站未被第三者冒充。此处的证书叫作“服务器证书”,同样由认证中心发行。个人的证书与他的有邮箱信息相对应,而服务器证书与域名信息相对应。因此,我们还可以确认网站域名和存储网站本身内容的服务器是由同一个组织来管理的。数字证书就是像这样通过认证中心来担保公开密钥的制作者,这一系列技术规范被统称为“公钥基础设施”。HTTPS数字证书网站配置https访问时,需要向相关权威机构申请数字证书,申请到数字证书后,将数字证书配置到项目里。我们就可以用浏览器通过https来访问这个网站了,这个权威机构是被浏览器官方授予了颁发权限,所以此处根节点是浏览器。如图所示,一个开启了https的网站,给你颁发证书的机构是浏览器官方指定的,所以浏览器就会显示连接是安全的。

0
0
0
浏览量564
超超

消息认证码与数字签名的理解

消息认证码消息认证码可以实现”认证“和”检测篡改“这两个功能。秘文的内容在传输过程中可能会被篡改,这会导致解密后的内容发生变化,从而产生误会。消息认证码就是可以预防这种情况发生的机制。消息篡改图解正常情况假设,A在B处购买商品,需要将商品编号abc告诉B。 此处A使用共享密钥加密对消息进行加密。A通过安全的方法将密钥发送给了B。 A使用双方共有的密钥对消息进行加密。 A把密文发送给B,B收到后对密文进行解密,最终得到了原本的商品编号abc。 消息被监听以上是没有出现问题时的流程,然后在这个过程中可能会发生下面的情况。 假设A发送给B的密文在通信过程中被X恶意篡改了,而B收到密文后没意识到这个问题。 B对被篡改的密文进行解密,得到消息xyz。 B以为A订购的是标号为xyz的商品,于是将错误的商品发送给了A。 解决监听问题如果使用消息认证码,就能检测出消息已经被篡改。接下来我们回到A正要向B发送密文的时候。 A生成了一个用于制作消息认证码的密钥,然后使用安全的方法将密钥发送给了B。 接下来A使用密文和密钥生成一个值,此处生成的是7f05。这个由「密钥和密文生成的值就是消息认证码」,以下简称MAC。 A将MAC(7f05)和密文发送给B。 和A一样,B也需要使用密文和密钥来生成MAC。经过对比,B可以确认自己计算出来的7f05和A发来的7f05一致。 接下来,B只需使用密钥对密文进行解密即可,最终B成功取得了A发送过来的商品编号abc。 验证消息认证码接下来,我们验证下使用消息消息认证码之后,X监听数据的情况,此时我们回到A正要向B发送密文的时候。 假设A向B发送密文和MAC时,X对密文进行了篡改。 B使用该密文计算MAC,得到的值时b85c,发现和收到的MAC不一致。 由此,B意识到密文或者MAC,甚至两者都可能遭到了篡改。于是B废弃了收到的密文和MAC,由A提出再次发送的请求。❝加密仅仅是一个数值计算和处理的过程,所以即使密文被篡改了,也能够进行解密相关的计算。❞使用场景如果原本消息是很长的句子,那么它被篡改后意思会变得很奇怪,所以接收者有可能会发现它是被篡改过的。但是,如果原本的消息就是商品编号等无法被人们直接理解的内容,那么解密后接收者便很难判断它是否被篡改。由于密码本身无法告诉人们消息是否被篡改,所以就需要使用消息认证码来检测。缺陷在使用消息认证码的过程中,AB双方都可以对消息进行加密并且算出MAC。也就是说,我们无法证明原本的消息是A生成的还是B生成的。因此,加入A是坏人,他就可以在自己发出消息后声称”这条消息是B捏造的“,而否认自己的行为。如果B是坏人,他也可以自己准备一条消息,然后声称”这是A发给我的消息“。使用MAC时,生成的一方和检测的一方持有同样的密钥,所以不能确定MAC由哪方生成,这个问题可以由下方的”数字签名“来解决。数字签名数字签名不仅可以实现消息认证码的认证和检测篡改功能,还可以预防是否否认问题的发生。由于在消息认证码中使用的是共享密钥加密,所以持有密钥的收信人也有可能是消息的发送者,这样是无法预防事后否认行为的。而数字签名只有发信人才能生成的,因此使用它就可以确定谁是消息的发送者了。特征图解假设A要向B发送消息 在发送前A给消息加上数字签名。数字签名只能由A生成。 只要发送的消息上有A的数字签名,就能确定消息的发送者就是A。 B可以验证数字签名的正确性,但无法生成数字签名。 数字签名生成图解数字签名的生成使用的是「公开密钥加密」。 首先,A准备好需要发送的信息、私有密钥和公开密钥。由消息的发送着来准备这两个密钥,这一点与公开密钥加密有所不同。 A将公开密钥发送给B A使用私有密钥加密消息,加密后的消息就是数字签名。 A将消息和签名都发送给了B B使用公开密钥对密文(签名)进行解密。 B对解密后的消息进行确认,看他是否和收到的消息一致。流程到此结束。 缺陷公开密钥加密的加密和解密都比较耗时,为了节约运算时间,实际上不会对消息直接进行加密,而是求得消息的哈希值,再对哈希值进行加密,然后将其作为签名来使用。 使用数字签名后B会相信消息的发送者就是A,但实际上也有可能是X冒充了A。其根本原因在于使用公开密钥加密无法确定公开密钥的制作者是谁,收到的公开密钥上也没有任何制作者的信息。因此,公开密钥有可能是由某个冒充A的人生成的。解决方案数字证书可以解决这一问题,数字证书的文章将在后面发出,欢迎各位感兴趣的开发者持续关注。写在最后

0
0
0
浏览量563
万码EZQPETUV

Chrome 浏览器出现 “Refused to execute script from” 的正确对应方法?

用Chrome浏览网站,执行一个javascript时,出现如下错误: Refused to execute script from 'http://mysite.com/info?no=31&magic=9543' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled. 其他浏览器,如火狐就没问题。 在StackOverflow上得知的一种简单方式是设置 HTTP header X-XSS-Protection: X-XSS-Protection: 0 http://stackoverflow.com/questions/1547884/refused-to-execute-a-javascript-script-source-code-of-script-found-within-reque 这是最好的解决办法吗?

0
1
0
浏览量198
超超

数据传输安全与加密算法深入解析

这个专栏将深入探讨数据传输过程中可能遇到的安全问题,并提供相应的解决方案。我们将详细解释哈希函数的原理和应用,探讨共享密钥加密和公开密钥加密的区别与应用场景,以及混合加密的概念与实践。我们还将解释迪菲赫尔曼密钥交换算法的工作原理和安全性,以及消息认证码和数字签名的作用与区别。最后,我们将深入探讨数字证书的概念和用途。通过这个专栏,你将深入了解数据传输安全和加密算法的核心知识,以及如何应用它们来保护敏感数据的安全性。

0
0
0
浏览量3301