垂直深耕企业市场价值高】信息安全行业事关国家安全,我给你发送一条消息

【公司概况:商业密码领域佼佼者】北京中宇万通科技股份有限公司于2005年成立,公司专注于信息安全与软件开发领域定位于满足我国政府机关、大型事业单位的信息化以及信息安全需求。公司以商用密码产品的生产与销售为核心业务,提供网络边界安全接入、移动互联安全等信息安全解决方案。公司是国家高新技术企业,经过十余年的发展,获得了一系列行业资质认证,产品业务受到广泛认可。

0. 何谓安全?

对于信息安全性的重要性,我想大家都不会否认。那么具体来说应该具有哪些特性才能称之为安全呢?举个简单的例子:我给你发送一条消息“借给我100元”,当你收到这条消息并且处理后你的账户里面会少出来100块,我的账户会多出来100块。在这个过程中,你是消息接收方,我是消息发送方。

  1. 作为通信双方的你我都不希望让其他人能读懂这条消息,这是信息的机密性即消息在传递过程中不被其他人解读
  2. 作为通信双方的你我都不希望消息内容变成”借老子1000块!”(操,借钱还这么牛逼,100块都不给你,还要1000块!死去…),这是信息的完整性即可以校验出信息在传送过程中是否被篡改
  3. 作为消息接收方的你需要确认是不是真正的我给你发的借钱的消息吧,会不会是个诈骗犯要骗我100块!这是对信息的认证即接收者要可以验证消息的发送者确实是自己希望的发送者
  4. 作为消息接收方的你肯定不希望在借给了我100块之后,我耍无赖失口否认说没借过你钱,这是信息的不可否认性即消息发送者不可以否认说这个信息不是我发送的

总结来说,在通信过程中,满足这4个特征:机密性完整性,认证,不可否认性,就可以认为信息是安全的那么接下来的几个小节来介绍一下有那些工具可以使得我们在传递消息的时候具有以上4个特征。

   
【行业概况:信息安全问题备受关注,新技术新领域带来持续市场需求】棱镜门丑闻曝光后,各国政府和企业机构高度重视信息安全建设,全球信息安全市场爆发增长。我国大力发展信息安全事业,《软件和信息技术服务业发展规划(2016-2020年)》提出到“十三五”末信息安全产业规模达到2000亿元,年均增长20%以上。随着物联网、云计算等新领域深入日常生活,其安全建设问题不可忽视,因此信息安全市场蕴含巨大商机。

1. 对称密码-对称密钥(Symmetric Cryptography)

对称密码加密可以保障信息的机密性。举一个简单的例子,一把锁,两把相同的钥匙,就是对称密码;即:使用相同的密钥来加密和解密。没有密钥的其他人是无法解读信息的真正内容是什么的。常见到两个对称加密标准有DES和AES。

DES是一种对称密钥加密算法,在1976年被美国联邦政府的国家标准局确定为联邦资料处理标准,随后在国际上广泛流传开来。它基于使用56位密钥的对称算法。现在现在已经不是一种安全的加密方法,主要因为它使用的56位密钥过短。后来又发展出了3DES(即执行三次DES加密)。由于DES已经不再安全,后来又推出了新的对称加密标准AES,采用的算法为Rijndael。算法的具体实现逻辑这里不去解释,这里关注的是如何利用它们(即,保障信息的机密性的手段)。看一下简单的加密解密的数学公式:

  1. 加密:encrypted_data = encrypt_function(message, key)
  2. 解密:message = decrypt_function(encrypted_data, key)

C#使用AES的代码如下:

/// <summary>
///  AES加密
/// </summary>
/// <param name="key">128bit,192bit,125bit</param>
/// <returns></returns>
public static byte[] AESEncrypt(this byte[] value, byte[] key)
{
    //todo 参数检查
    using (var symmetricAlgorithm = Aes.Create())
    {
        symmetricAlgorithm.Key = key;
        symmetricAlgorithm.Mode = CipherMode.ECB;
        symmetricAlgorithm.Padding = PaddingMode.PKCS7;
        //加密
        using (var encryptor = symmetricAlgorithm.CreateEncryptor())
        {
            return encryptor.TransformFinalBlock(value, 0, value.Length);
        }
    }
}

/// <summary>
///  AES解密
/// </summary>
/// <param name="key">128bit,192bit,125bit</param>
/// <returns></returns>
public static byte[] AESDecrypt(this byte[] value, byte[] key)
{
    //todo 参数检查
    using (var symmetricAlgorithm = Aes.Create())
    {
        symmetricAlgorithm.Key = key;
        symmetricAlgorithm.Mode = CipherMode.ECB;
        symmetricAlgorithm.Padding = PaddingMode.PKCS7;
        //解密
        using (var encryptor = symmetricAlgorithm.CreateDecryptor())
        {
            return encryptor.TransformFinalBlock(value, 0, value.Length);
        }
    }
}

static void Main()
{
    var value = "lnh".ToBytes(Encoding.UTF8);
    //构造128bit的key,guid正好是128,权且当作key了。
    var key = Guid.NewGuid().ToByteArray();
    var encryptedData = value.AESEncrypt(key);
    var decryptedData = encryptedData.AESDecrypt(key);
    var decryptedDataString = Encoding.UTF8.GetString(decryptedData);
    Console.WriteLine();
}

.Net库已经封装好了一些对称加密的类,开箱即用:

图片 1

   
【竞争格局:信息安全细分领域众多,垂直深耕企业市场价值高】信息安全行业事关国家安全,标准化要求较高,外资难以介入。目前信息安全市场的细分程度较高,不同的细分市场领域有相应的专业厂商,竞争主要集中在各个细分领域内,没有任何一个企业能掌握信息安全领域的所有技术,市场总体的品牌集中度相对较低。目前,国内涌现出了启明星辰、蓝盾股份龙头。在商用密码领域,中宇万通不断研发新技术,凭借过硬的技术实力,与公安、税务、央企等事业单位开展深入的业务合作,与吉大正元、格尔软件等同属第一梯队。

1.1 遗留问题

密钥配送问题:共享的密钥如何交到接受消息方的手上呢?双方可以事先共同约定一个密钥,但是这种办法是无法满足互联网规模的需要的,互联网规模的环境是假设通信双方事先并不知道对方的存在,怎么事先约定呢,行不通吧。

下面接下来的公钥密钥可以解决这个问题。

   
【竞争优势:过硬技术+持续创新不断提高市场地位】公司核心骨干层具有较为丰富的行业经验与较强的研发实力,依托十余年的技术积累逐步推出了一系列商用密码产品。2017年商用密码及安全应用系统产品收入较上年同期增长26.65%,技术开发及服务收入较上年同期增长37%。公司紧密追踪市场新动向在网关产品外,研发了SIM
型密码卡、视频安全接入等新产品,将成为新的增长点。

2. 公钥密码-非对称密钥(Asymmetric Cryptography)

对称密码加密可以解决信息的机密性的问题,但是却无法提供双方如何才能得到加密所用密钥的途径。我们回到最初的目的想一想,我们想要的机密性的核心在于别人无法取得信息的真实内容,也就是解密;而如何生成这个机密的信息,其实并不是我们关注的点,你能生成,他能生成,都没区别,只要我控制住只有我才能解密,那么机密性的问题就解决了。所以解决密钥配送的问题的关键就在于,把密钥分成两部分,一个加密用,一个解密用,它们总是成对出现的。配送的是加密用的密钥(也叫公钥),解密用的叫私钥,这个只有我自己知道,不会在任何地方传输,那么也就不存在配送的问题了。

其实很多计算机中的问题都是无解的,往往却又是有解决办法的,它的解决办法其实并不是直接的解决这个问题,而是规避掉这个问题,使得它不在是一个问题的。比如密钥配送的问题,如果说我们有安全的方式解决密钥配送的问题,直接使用这个安全的方式配送我们想要传递的信息不就是了,我们还绕个弯配送密钥干什么呢。公钥密码其实并未解决密钥配送的问题,而是使得它不再是个问题,即:公钥可以公开给任何人,不再需要保密(本质上来说,密钥和待加密的信息同样重要),而是通过控制解密来达到我们想要的机密性,绕过了如何机密的配送密钥的问题。

公钥密码就是这么一个简单的原理:公钥(=public
key)加密,私钥(=private
key)解密,它可以保障信息的机密性,同时解决密钥的配送问题
。那么这个时候通信双方的流程就是这样的:

  1. 发送方向接收方请求一个  public key  ;
  2. 发送方使用 public key 加密消息, public
    key 和加密的消息泄露都没关系,因为只有 private
    key 才能解密;
  3. 接收方用 private key 解密消息。

至于如何产生出来这样一对 public key 和 private
key
以及相对于的加密解密算法,这其中涉及到很复杂的数学问题,这里就不展开介绍了(笔者也不懂…)。我们看一下最广泛使用的公钥密码算法RSA在C#里面怎么使用吧:

/// <summary>
///  RSA加密
/// </summary>
/// <param name="publicKey">公钥</param>
/// <returns></returns>
public static byte[] RSAEncrypt(this byte[] value, string publicKey)
{
    //todo 参数检查
    using (var asymmetricAlgorithm = new RSACryptoServiceProvider())
    {
        asymmetricAlgorithm.FromXmlString(publicKey);
        return asymmetricAlgorithm.Encrypt(value,false);
    }
}

/// <summary>
///  RSA解密
/// </summary>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public static byte[] RSADecrypt(this byte[] value, string privateKey)
{
    //todo 参数检查
    using (var asymmetricAlgorithm = new RSACryptoServiceProvider())
    {
        asymmetricAlgorithm.FromXmlString(privateKey);
        return asymmetricAlgorithm.Decrypt(value,false);
    }
}

static void Main()
{
    string privateKey;
    string publicKey;
    using (var asymmetricAlgorithm = RSA.Create())
    {
        privateKey = asymmetricAlgorithm.ToXmlString(true);
        publicKey = asymmetricAlgorithm.ToXmlString(false);
    }

    var value = "lnh".ToBytes(Encoding.UTF8);
    //公钥加密
    var encryptedData = value.RSAEncrypt(publicKey);
    //私钥解密
    var decryptedData = encryptedData.RSADecrypt(privateKey);

    var decryptedDataString = Encoding.UTF8.GetString(decryptedData);
    Console.WriteLine();
}

.Net库中已经提供了公钥密码相关的类,开箱即用:

图片 2

   
【成长空间:聚焦互联网、物联网,成为信息安全与数据整合方案供应商】公司保持较高的核心技术研发能力和研发创新力度,物联网安全、云安全领域率先投入研发,推出视频安全网关、签名服务器、智能应用网关、行为管理系统等产品,形成了一系列商用安全解决方案,逐步向技术服务商转变。与此同时,公司建立高水平的直销团队与技术支持团队,提供全套信息安全咨询服务,扩大市场占有率,2017年实现净利润增长50.27%。

2.1 对公钥密钥的攻击

中间人攻击:这钟类型的攻击发生在上述流程中的第一步,即发送方A向接收方B请求 public
key 的时候。这时有一个拦路打劫的家伙M,截获了这个 public
key ,自己据为己有。然后M把自己的一个 public
key 给到了A,A是浑然不觉,傻乎乎的用这个假的 public
key
加密了信息,发送了出去,这时候M拦截到了这个消息,用自己的 private
key 解密了这个消息,然后篡改一番,用真正的 public
key
进行加密,发给了B。这个时候B以为是A发送的,A也以为自己发给了B,其实都被M给玩了…文字可能不是很清晰,看图:

图片 3

    【盈利预测】根据公司现有业务情况,测算公司18-19年EPS
分别为0.81元、1.07元,对应PE8.82、6.64。

2.2 遗留问题

公钥的认证问题:公钥密钥可以解决规避掉的配送问题,但是新问题又来了,这个公钥真的是你的吗?针对上述的中间人攻击,其实我们发现,获取公钥的这一方并不能确认自己收到的公钥就是自己真正请求的那一方提供的。这个问题先放一放(后续会介绍),下面先看看保障信息的完整性方面有那些工具可用。

3. 密码散列函数(Cryptographic hash function)

密码散列函数可以保障的信息完整性,用来校验要传递的信息是否被篡改过。比如通常在下载文件的时候,官方的网站上都会列出来其MD5或者SHA1的值来校验。它的工作原理和要求大致如下:

  1. 输入一组数据message,然后得到一组简短的数据hash,只要是采用相同的算法,输入message就能得到hash:hash
    = hash_function (message)
  2. 其过程是不可逆的,你不能由hash得出message;
  3. 满足message的微小变化会(比如只改动1字节)会使得hash产生巨大的变化(就好比两个双胞胎,各处都很像,但是他们的指纹却不是相同的);
  4. 两组不同的消息message1和message2,不能得出相同的hash(理论上可以,只是要尽可能的使这个过程困难)。

常用的密码散列函数(算法)有Message Digest Algorithm以及Secure Hash
Algorithm。

3.1 MD5(Message Digest Algorithm 5)

中文明为消息摘要算法第五版,这也说明其实它也有前面几个版本,比如MD4(这里就不介绍了)。MD5算法是输入任意长度的数据(Message),然后算出固定长度的数据 16byte=128bits ,用16进制表示这16个byte就是32位。C#使用MD5的代码如下:

 1 /// <summary>
 2 /// MD5摘要算法
 3 /// </summary>
 4 /// <param name="value"></param>
 5 /// <returns>128 bits,16 byte array</returns>
 6 public static byte[] ToMD5(this byte[] value)
 7 {
 8     if (value == null || value.Length == 0)
 9     {
10         throw new ArgumentNullException(nameof(value));
11     }
12     using (var hashAlgorithm = MD5.Create())
13     {
14         return hashAlgorithm.ComputeHash(value);
15     }
16 }

再一次指出,md5的结果是固定的 16byte=128bits ,用16进制表示是32个字符。网上由很多的16进制16个字符的md5,其实这都不是完整的md5,只是截取了32位中的16位而已。

3.2 SHA ( Secure Hash Algorithm )

 从使用者的角度来看,MD5和SHA没有什么本质区别,差异在于其算法的实现方式,生成的hash的长度,其抗攻击破解的难度不一样。此外由于SHA的强度比MD5要大,所以在计算SHA的时候,所消耗的资源(时间,空间都有)也会比MD5要多。即使如此,现在MD5(128bit)和SHA-1(160bit)均已遭到了破解:。SHA家族现有的以下成员如下有SHA-1(160)、SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)和SHA-3(SHA3-224,SHA3-256,SHA3-384,SHA3-512)。C#中使用SHA256的代码如下:

/// <summary>
/// SHA256哈希算法
/// </summary>
/// <returns>256 bits,32 byte array</returns>
public static byte[] ToSHA256(this byte[] value)
{
    if (value == null || value.Length == 0)
    {
        throw new ArgumentNullException(nameof(value));
    }
    using (var hashAlgorithm = SHA256.Create())
    {
        return hashAlgorithm.ComputeHash(value);
    }
}

.NET的库已经帮我们封装好了密码散列函数相关的类,开箱即用。

图片 4

3.3 密码散列函数的实际应用

  1. 检查文件是否被修改:上面一开始举得例子下载文件的例子。
  2. 基于口令的加密:通常我们在存储用户的密码的时候,都会采用这种方式(除非你是csdn),一般还会辅助的加上盐。
  3. 消息认证码:后面介绍到到。
  4. 数字签名:后面会介绍到。
  5. 伪随机数生成器:后面会介绍到。

3.4 针对密码散列函数的攻击

  1. 强碰撞性攻击:比如上面提到的Google破解了SHA-1,即使用大量的计算来找出两个数据message不一样,但是hash值却一样的过程,如果找到了这样的两块数据,那么再使用这个hash作为数据的完整性校验的手段,其实已经没有意义了。解决办法是升级SHA-2,增大计算出这样两块数据的难度。
  2. 暴力破解:比如网上很多的MD5的解密,其实原理在于他们有大量的MD5
    hash库,比如 123456 的MD5是 e10adc3949ba59abbe56e057f20f883e
    ,那么在你给我一个 e10adc3949ba59abbe56e057f20f883e
    的时候,我就知道你的原文是 123456
    。解决办法是加盐,增大这种暴力比对的难度。

针对上面两种攻击方式都是在于增加破解难度,使其在现有的计算能力下不能轻易的被攻破,没有绝对的安全,只是相对上来说是安全的,当破解你带来的收益要低于其破解成本的时候,你才是安全的。

3.5 遗留问题

hash被篡改了:比如上面下载文件的时候官方会给出MD5或者SHA1的hash值,这里我们假设一下,官方提供hash值的渠道被黑掉了,给了你一个篡改过的hash值,然后你下载了一个被篡改过的文件,你是分辨不出来的。其实我们下载文件,然后比对官方给的hash值,这里是假设官方的hash值是没有被篡改的。

那么接下来的消息认证码MAC是可以解决这个问题。

4. 消息认证码(Message Authentication Code)

消息认证码(MAC)的作用就是在保障完整性的基础上,同时提供认证(*认证=消息是来自真正的发送者)***的功能,用来解决上述密码散列函数遗留的问题。可以简单的这样理解,MAC是在密码散列函数+共享密钥后算出的hash值,由于密钥是只有通信双方才知道的,那么就可以认为通过MAC得到的hash可以保障信息的完整性以及同时提供认证的能力。**这里我们假设双方不存在密钥配送的问题(即双方已经持有相同的密钥,至于是通过什么方式传递的,这里先不关心)。

使用密码散列函数可以实现MAC,这种方式称为HMAC(Hash Message
Authentication Code): 和
。计算公式可以简单的理解为:mac
= mac_function (message,key)
。C#中使用HMAC的代码如下:

/// <summary>
/// HMACSHA1算法
/// </summary>
/// <returns>160 bits,20 byte array</returns>
public static byte[] ToHMACSHA1(this byte[] value,byte[] key)
{
    if (value == null || value.Length == 0)
    {
        throw new ArgumentNullException(nameof(value));
    }
    if (key == null || key.Length == 0)
    {
        throw new ArgumentNullException(nameof(key));
    }
    using (var macAlgorithm =new HMACSHA1())
    {
        macAlgorithm.Key = key;
        return macAlgorithm.ComputeHash(value);
    }
}

static void Main()
{
    var value = "lnh".ToBytes();
    var key = "123".ToBytes();
    var mac = value.ToHMACSHA1(key);
    Console.WriteLine();
}

.Net类库中开箱即用的MAC相关的类,开箱即用:

图片 5

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图