精华内容
下载资源
问答
  • RSA密钥长度、明文长度和密文长度

    千次阅读 2018-10-18 09:58:51
    本文介绍RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,天缘以后还会补充几篇RSA基础知识专题文章,用最简单最通俗的语言描述RSA,让各位了解...

    本文介绍RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,天缘以后还会补充几篇RSA基础知识专题文章,用最简单最通俗的语言描述RSA,让各位了解RSA算法本身其实也很简单,RSA的复杂度是因为数学家把效率和安全也考虑进去的缘故。

    本文先只谈密钥长度、明文长度和密文长度的概念知识,RSA的理论及示例等以后再谈。提到密钥,我们不得不提到RSA的三个重要大数:公钥指数e、私钥指数d和模值n。这三个大数是我们使用RSA时需要直接接触的,理解了本文的基础概念,即使未接触过RSA的开发人员也能应对自如的使用RSA相关函数库,无需深入了解e、d、n是如何生成的,只需要知道我该如何用、要注意什么。

    一、密钥长度

    1、密钥是指谁?

    首先我们说的“密钥”是指谁?由于RSA密钥是(公钥+模值)、(私钥+模值)分组分发的,单独给对方一个公钥或私钥是没有任何用处,所以我们说的“密钥”其实是它们两者中的其中一组。但我们说的“密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096…

    2、模值主流长度是多少?

    目前主流密钥长度至少都是1024bits以上,低于1024bit的密钥已经不建议使用(安全问题)。那么上限在哪里?没有上限,多大都可以使用。所以,主流的模值是1024位,实际运算结果可能会略小于1024bits,注意,这个值不是绝对的,跟素数的生成算法有关系,只是告诉素数生成器“帮我生成一个接近1024位的素数而已”,然后生成器“好,给您一个,这个差不多1024位”。

    素数生成器这么厉害?说生成1024位就会出个1024位的大整数?真实的情况是素数生成器也只是在1024bits对应的整数附近进行“摸索”而已,大家其实都不容易,又要快又要准确又要随机性,那么素数生成器也只能应付一下,找到1024位的算是好运,没找到1024位,1023位也照样送出来:)。

    3、公钥指数如何确定?

    公钥指数是随意选的,但目前行业上公钥指数普遍选的都是65537(0x10001,5bits),该值是除了1、3、5、17、257之外的最小素数,为什么不选的大一点?当然可以,只是考虑到既要满足相对安全、又想运算的快一点(加密时),PKCS#1的一个建议值而已。

    有意的把公钥指数选的小一点,但是对应私钥指数肯定很大,意图也很明确,大家都要用公钥加密,所以大家时间很宝贵,需要快一点,您一个人私钥解密,时间长一点就多担待,少数服从多数的典型应用。

    4、私钥指数如何确定?

    公钥指数随意选,那么私钥就不能再随意选了,只能根据算法公式(ed%k=1,k=(p-1)(q-1))进行运算出来。那么私钥指数会是多少位?根据ed关系,私钥d=(x*k+1)/e,所以单看这个公式,私钥指数似乎也不是唯一结果,可能大于也可能小于1024bits的,但我们习惯上也是指某个小于1024bits的大整数。

    包括前文的公钥指数,在实际运算和存储时为方便一般都是按照标准位长进行使用,前面不足部分补0填充,所以,使用保存和转换这些密钥需要注意统一缓冲区的长度。

    二、明文长度

    网上有说明文长度小于等于密钥长度(Bytes)-11,这说法本身不太准确,会给人感觉RSA 1024只能加密117字节长度明文。实际上,RSA算法本身要求加密内容也就是明文长度m必须0<m<n,也就是说内容这个大整数不能超过n,否则就出错。那么如果m=0是什么结果?普遍RSA加密器会直接返回全0结果。如果m>n,运算就会出错?!那怎么办?且听下文分解。

    所以,RSA实际可加密的明文长度最大也是1024bits,但问题就来了:

    如果小于这个长度怎么办?就需要进行padding,因为如果没有padding,用户无法确分解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难理解,因为不确定后面的0是内容还是内容结束符。

    只要用到padding,那么就要占用实际的明文长度,于是才有117字节的说法。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

    如果大于这个长度怎么办?很多算法的padding往往是在后边的,但PKCS的padding则是在前面的,此为有意设计,有意的把第一个字节置0以确保m的值小于n。

    这样,128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

    关于PKCS#1 padding规范可参考:RFC2313 chapter 8.1,我们在把明文送给RSA加密器前,要确认这个值是不是大于n,也就是如果接近n位长,那么需要先padding再分段加密。除非我们是“定长定量自己可控可理解”的加密不需要padding。

    三、密文长度

    密文长度就是给定符合条件的明文加密出来的结果位长,这个可以确定,加密后的密文位长跟密钥的位长度是相同的,因为加密公式:

    C=(P^e)%n

    所以,C最大值就是n-1,所以不可能超过n的位数。尽管可能小于n的位数,但从传输和存储角度,仍然是按照标准位长来进行的,所以,即使我们加密一字节的明文,运算出来的结果也要按照标准位长来使用(当然了,除非我们能再采取措施区分真实的位长,一般不在考虑)。

    至于明文分片多次加密,自然密文长度成倍增长,但已不属于一次加密的问题,不能放到一起考虑。

    展开全文
  • 问题:已知十段密文,以及一段待解出的特定密文,如何获取特定密文明文?已知:所有的密文都是使用同样的key,使用stream cipher(流加密),只是简单使用原文和key异或得到密文,而且key是随机的,长于所有的原文...

    问题:已知十段密文,以及一段待解出的特定密文,如何获取特定密文的明文?

    已知:所有的密文都是使用同样的key,使用stream cipher(流加密),只是简单使用原文和key异或得到密文,而且key是随机的,长于所有的原文

    解决方法:主要思想在于利用空格(space),因为空格与任意大小写字母异或都能够得到大小写相反的同样字母,比如space与a异或可以得到A,可参考如下的ASCII表:
    这里写图片描述

    1、首先找出待解密文的空格
    利用十段密文分别与待解密文异或,如果异或的结果同一位置都是字母,而且密文内容不一样,那么可以暂且判定当前位置的待解密文的原文是空格,因为密文异或的结果和明文异或的结果是相同的,那么既然不同的明文和同一个明文异或结果都是字母,那就可以暂且判断这个明文是空格,如下证明了为何明文异或结果与密文异或结果相同:
    这里写图片描述

    2、再获取待解密文中的字母
    利用总的十一段密文相互异或,使用1中的方法找出十段密文中某个位置上的空格,那么就可以使用该位置待解密文与具有空格的密文异或的结果再与空格异或即可获得待解密文的原文。理由在于我们知道明文之间的异或结果与密文的异或结果相同,已知一个明文是空格,则只需要在等式两边分别再异或一个空格,则可以消除明文这一边的空格剩下待解明文,如下图所示(假设我们利用1的方法找到P2是space,则可以得出下例)
    这里写图片描述

    3、最后再重新对待解密文中在1中暂认为是空格的地方重判断
    也就是再利用2中的方法即可。因为比如说我们使用ASCII码的237位与191位异或,也会得到字母,所以有可能当前target其实并不是空格,因此我们还需要再反过来判断一次。

    代码如下所示:

    c1.txt(总共十段密文)
    315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e
    234c02ecbbfbafa3ed18510abd11fa724fcda2018a1a8342cf064bbde548b12b07df44ba7191d9606ef4081ffde5ad46a5069d9f7f543bedb9c861bf29c7e205132eda9382b0bc2c5c4b45f919cf3a9f1cb74151f6d551f4480c82b2cb24cc5b028aa76eb7b4ab24171ab3cdadb8356f
    32510ba9a7b2bba9b8005d43a304b5714cc0bb0c8a34884dd91304b8ad40b62b07df44ba6e9d8a2368e51d04e0e7b207b70b9b8261112bacb6c866a232dfe257527dc29398f5f3251a0d47e503c66e935de81230b59b7afb5f41afa8d661cb
    32510ba9aab2a8a4fd06414fb517b5605cc0aa0dc91a8908c2064ba8ad5ea06a029056f47a8ad3306ef5021eafe1ac01a81197847a5c68a1b78769a37bc8f4575432c198ccb4ef63590256e305cd3a9544ee4160ead45aef520489e7da7d835402bca670bda8eb775200b8dabbba246b130f040d8ec6447e2c767f3d30ed81ea2e4c1404e1315a1010e7229be6636aaa
    3f561ba9adb4b6ebec54424ba317b564418fac0dd35f8c08d31a1fe9e24fe56808c213f17c81d9607cee021dafe1e001b21ade877a5e68bea88d61b93ac5ee0d562e8e9582f5ef375f0a4ae20ed86e935de81230b59b73fb4302cd95d770c65b40aaa065f2a5e33a5a0bb5dcaba43722130f042f8ec85b7c2070
    32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd2061bbde24eb76a19d84aba34d8de287be84d07e7e9a30ee714979c7e1123a8bd9822a33ecaf512472e8e8f8db3f9635c1949e640c621854eba0d79eccf52ff111284b4cc61d11902aebc66f2b2e436434eacc0aba938220b084800c2ca4e693522643573b2c4ce35050b0cf774201f0fe52ac9f26d71b6cf61a711cc229f77ace7aa88a2f19983122b11be87a59c355d25f8e4
    32510bfbacfbb9befd54415da243e1695ecabd58c519cd4bd90f1fa6ea5ba47b01c909ba7696cf606ef40c04afe1ac0aa8148dd066592ded9f8774b529c7ea125d298e8883f5e9305f4b44f915cb2bd05af51373fd9b4af511039fa2d96f83414aaaf261bda2e97b170fb5cce2a53e675c154c0d9681596934777e2275b381ce2e40582afe67650b13e72287ff2270abcf73bb028932836fbdecfecee0a3b894473c1bbeb6b4913a536ce4f9b13f1efff71ea313c8661dd9a4ce
    315c4eeaa8b5f8bffd11155ea506b56041c6a00c8a08854dd21a4bbde54ce56801d943ba708b8a3574f40c00fff9e00fa1439fd0654327a3bfc860b92f89ee04132ecb9298f5fd2d5e4b45e40ecc3b9d59e9417df7c95bba410e9aa2ca24c5474da2f276baa3ac325918b2daada43d6712150441c2e04f6565517f317da9d3
    271946f9bbb2aeadec111841a81abc300ecaa01bd8069d5cc91005e9fe4aad6e04d513e96d99de2569bc5e50eeeca709b50a8a987f4264edb6896fb537d0a716132ddc938fb0f836480e06ed0fcd6e9759f40462f9cf57f4564186a2c1778f1543efa270bda5e933421cbe88a4a52222190f471e9bd15f652b653b7071aec59a2705081ffe72651d08f822c9ed6d76e48b63ab15d0208573a7eef027
    466d06ece998b7a2fb1d464fed2ced7641ddaa3cc31c9941cf110abbf409ed39598005b3399ccfafb61d0315fca0a314be138a9f32503bedac8067f03adbf3575c3b8edc9ba7f537530541ab0f9f3cd04ff50d66f1d559ba520e89a2cb2a83
    
    
    target.txt(待解密文)
    275a1ae0a6b5f8bfe8115441ed0ffa654acabc58de178c46800804bbe95aeb
    
    
    
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    #include <set>
    using namespace std; 
    int temptemp[1000] = {0}; //暂存16进制转为10进制的数值 
    int tar[1000] = {0};      //存储target的10进制数 
    int cyp[20][1000] = {0};  //存储10个密文的10进制数 
    int tar_xor_cyp[20][1000] = {0}; //存储target与10个密文异或的结果 
    int tar_len = 0;          //存储target的长度 
    int tar_blank[1000] = {0}; 
    //转换进制 
    void transform_16_to_10(string s){
        int len = s.length();
        memset(temptemp,0,sizeof(temptemp));
        for(int i = 0 ; i < len/2 ; i++){
            int temp = 0;
            int t = 0;
            if(s[2*i] >= 'a' && s[2*i] <= 'f'){
                t = s[2*i] - 'a' + 10;
            }else{
                t = s[2*i] - '0';
            }
            temp += t * 16;
            if(s[2*i +1] >= 'a' && s[2*i +1] <= 'f'){
                t = s[2*i +1] - 'a' + 10;
            }else{
                t = s[2*i +1] - '0';
            }
            temp += t;
            temptemp[i] = temp;
        }
    }
    
    //将target分别与10个密文异或 
    void do_xor(){
        ofstream out("tar_xor_cyp.txt");
        for(int j = 0 ; j < 10 ; j++){
            for(int i = 0 ; i < tar_len ; i++){
                tar_xor_cyp[j][i] = tar[i] ^ cyp[j][i];
                //out << (char)tar_xor_cyp[j][i] << " ";
                out << tar_xor_cyp[j][i] << " ";
            }
            out <<endl;
        }
        out.close();
    }
    
    //判断是否是字母 
    bool is_char(int t){
        if((t>= 65&&t<=90) || (t>=97 && t <= 122)){
            return true;
        }
        return false;
    }
    
    //获取target是否是空格 
    void get_blank_num(){
        set<int> set0;
        for(int i = 0 ; i < tar_len ; i++){
            set0.clear();
            for(int j = 0 ; j < 10 ; j++){
                if(is_char(tar_xor_cyp[j][i])){
                    set0.insert(cyp[j][i]);
                }
            }
            if(set0.size() >= 2){
                //cout << "blank_cyp:" << i << " " << tar[i] << " " << set0.size() << endl;
                tar_blank[i] = 1;
            } 
        }
    }
    
    
    //计算第i个cyp的第j位是不是空格 
    bool com_blank_of_cyp(int i, int j){  //第i个cyp第j位 
        set<int> set0;
        set0.clear();
        int xor_temp;
        xor_temp = tar[j] ^ cyp[i][j];
        if(is_char(xor_temp)){
            set0.insert(tar[j]);
        }
        for(int k = 0 ; k < 10 ; k++){
            if(k==i){
                continue;
            }else{
                xor_temp = cyp[i][j] ^ cyp[k][j];
                if(is_char(xor_temp)){
                    set0.insert(cyp[k][j]);
                }   
            }
        }
        if(set0.size() >= 2 ){
            return true;
        }else{
            //cout << "dont know j:" << j <<endl;
            return false;
        }
    }
    
    
    //获取第i位字符 
    void get_str_tar(){
        for(int i = 0 ; i < tar_len; i++){
            if(tar_blank[i] == 0){
                for(int j = 0 ; j < 10 ; j++){
                    if(com_blank_of_cyp(j,i)){ //计算第i个cyp的第j位是不是空格
                        //cout << "get_str_tar:" << i <<endl;
                        //cout <<"cyp[i][j]:" << cyp[i][j] <<endl;
                        int mn = cyp[j][i] ^ tar[i];
                        //cout << "mn:" << mn <<endl;
                        if(is_char(mn)){
                            if(mn>= 65 && mn<=90){
                                tar[i] = mn + 32;
                                //cout << "tar[i]:" <<i << " "<< tar[i] <<endl; 
                            }else{
                                tar[i] = mn - 32;
                            }
                        }
                        //tar[i] = cyp[j][i] ^ tar[i] ^ 32;
                        break;
                    }
                }
            }
            //对之前判定为空格的部分重新判断 
            else{
                for(int j = 0 ; j < 10 ; j++){
                    if(com_blank_of_cyp(j,i)){
                        //cout << "get_str_tar:" << i <<endl;
                        int mn = cyp[j][i] ^ tar[i];
                        //cout << "mn:" << mn <<" " << cyp[j][i] <<" " << tar[i] <<" "<<endl;
                        if(is_char(mn)){
                            tar_blank[i] = 0;
                            if(mn>= 65 && mn<=90){
                                tar[i] = mn + 32;
                                //cout << "tar[i]:" <<i << " "<< tar[i] <<endl; 
                            }else{
                                tar[i] = mn - 32;
                            }
                            break;
                        }
                        //tar[i] = cyp[j][i] ^ tar[i] ^ 32;
                    }
                }
            }
        }   
    }
    
    //输出原文 
    void get_plantext(){
        ofstream out("plaintext.txt");
        for(int i = 0 ; i < tar_len; i++){
            if(tar_blank[i] == 1){
                out << " ";
                cout << " ";
            }else{
                out << (char)tar[i];
                cout << (char)tar[i];
            }
        }
        out.close();
    }
    
    
    int main(){
        ifstream in("target.txt");
        ofstream out("look.txt");
        string str;
        if(in){
            while(getline(in,str)){
                tar_len = str.length() / 2;
                //cout << "tar_len:" << tar_len << endl;
                transform_16_to_10(str);
                for(int i = 0 ; i < str.length()/2 ; i++){
                    //获取target的16进制数值 
                    tar[i] = temptemp[i];
                    out << temptemp[i] << " ";
                }
                out <<endl;
            }
        }
        //cout << "target down" <<endl;
        in.close();
    
        //string str;
        ifstream in1("c1.txt");
        if(in1){
            int time = 0;
            while(getline(in1,str)){
                transform_16_to_10(str);
                for(int i = 0 ; i < str.length()/2 ; i++){
                    //获取十段密文的16进制数值 
                    cyp[time][i] = temptemp[i];
                    out << temptemp[i] << " ";
                }
                out <<endl;
                time++;
            }
        }
    
        for(int i = 0 ; i < 10; i++){
            for(int j = 0 ; j < tar_len; j++){
                out << cyp[i][j] <<" ";
            }
            out <<endl;
        }
    
        in1.close();
        //cout << "cyp down" <<endl;
        out.close();
    
        do_xor();       //将target与十段密文异或 
    
        get_blank_num();//获取target中空格的位置 
    
        get_str_tar();  //获取target中的字母 
    
        get_plantext(); //输出原文 
    
        return 0;
    }
    展开全文
  • 本文介绍RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,天缘以后还会补充几篇RSA基础知识专题文章,用最简单最通俗的语言描述RSA,让各位了解...

    本文介绍RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题,对第一次接触RSA的开发人员来说,RSA算是比较复杂的算法,天缘以后还会补充几篇RSA基础知识专题文章,用最简单最通俗的语言描述RSA,让各位了解RSA算法本身其实也很简单,RSA的复杂度是因为数学家把效率和安全也考虑进去的缘故。

    本文先只谈密钥长度、明文长度和密文长度的概念知识,RSA的理论及示例等以后再谈。提到密钥,我们不得不提到RSA的三个重要大数:公钥指数e、私钥指数d和模值n。这三个大数是我们使用RSA时需要直接接触的,理解了本文的基础概念,即使未接触过RSA的开发人员也能应对自如的使用RSA相关函数库,无需深入了解e、d、n是如何生成的,只需要知道我该如何用、要注意什么。

    一、密钥长度

    1、密钥是指谁?

    首先我们说的“密钥”是指谁?由于RSA密钥是(公钥+模值)、(私钥+模值)分组分发的,单独给对方一个公钥或私钥是没有任何用处,所以我们说的“密钥”其实是它们两者中的其中一组。但我们说的“密钥长度”一般只是指模值的位长度。目前主流可选值:1024、2048、3072、4096...

    2、模值主流长度是多少?

    目前主流密钥长度至少都是1024bits以上,低于1024bit的密钥已经不建议使用(安全问题)。那么上限在哪里?没有上限,多大都可以使用。所以,主流的模值是1024位,实际运算结果可能会略小于1024bits,注意,这个值不是绝对的,跟素数的生成算法有关系,只是告诉素数生成器“帮我生成一个接近1024位的素数而已”,然后生成器“好,给您一个,这个差不多1024位”。

    素数生成器这么厉害?说生成1024位就会出个1024位的大整数?真实的情况是素数生成器也只是在1024bits对应的整数附近进行“摸索”而已,大家其实都不容易,又要快又要准确又要随机性,那么素数生成器也只能应付一下,找到1024位的算是好运,没找到1024位,1023位也照样送出来:)。

    3、公钥指数如何确定?

    公钥指数是随意选的,但目前行业上公钥指数普遍选的都是65537(0x10001,5bits),该值是除了1、3、5、17、257之外的最小素数,为什么不选的大一点?当然可以,只是考虑到既要满足相对安全、又想运算的快一点(加密时),PKCS#1的一个建议值而已。

    有意的把公钥指数选的小一点,但是对应私钥指数肯定很大,意图也很明确,大家都要用公钥加密,所以大家时间很宝贵,需要快一点,您一个人私钥解密,时间长一点就多担待,少数服从多数的典型应用。

    4、私钥指数如何确定?

    公钥指数随意选,那么私钥就不能再随意选了,只能根据算法公式(ed%k=1,k=(p-1)(q-1))进行运算出来。那么私钥指数会是多少位?根据ed关系,私钥d=(x*k+1)/e,所以单看这个公式,私钥指数似乎也不是唯一结果,可能大于也可能小于1024bits的,但我们习惯上也是指某个小于1024bits的大整数。

    包括前文的公钥指数,在实际运算和存储时为方便一般都是按照标准位长进行使用,前面不足部分补0填充,所以,使用保存和转换这些密钥需要注意统一缓冲区的长度。

    二、明文长度

    网上有说明文长度小于等于密钥长度(Bytes)-11,这说法本身不太准确,会给人感觉RSA 1024只能加密117字节长度明文。实际上,RSA算法本身要求加密内容也就是明文长度m必须0<m<n,也就是说内容这个大整数不能超过n,否则就出错。那么如果m=0是什么结果?普遍RSA加密器会直接返回全0结果。如果m>n,运算就会出错?!那怎么办?且听下文分解。

    所以,RSA实际可加密的明文长度最大也是1024bits,但问题就来了:

    如果小于这个长度怎么办?就需要进行padding,因为如果没有padding,用户无法确分解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难理解,因为不确定后面的0是内容还是内容结束符。

    只要用到padding,那么就要占用实际的明文长度,于是才有117字节的说法。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

    如果大于这个长度怎么办?很多算法的padding往往是在后边的,但PKCS的padding则是在前面的,此为有意设计,有意的把第一个字节置0以确保m的值小于n。

    这样,128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

    关于PKCS#1 padding规范可参考:RFC2313 chapter 8.1,我们在把明文送给RSA加密器前,要确认这个值是不是大于n,也就是如果接近n位长,那么需要先padding再分段加密。除非我们是“定长定量自己可控可理解”的加密不需要padding。

    三、密文长度

    密文长度就是给定符合条件的明文加密出来的结果位长,这个可以确定,加密后的密文位长跟密钥的位长度是相同的,因为加密公式:

    C=(P^e)%n

    所以,C最大值就是n-1,所以不可能超过n的位数。尽管可能小于n的位数,但从传输和存储角度,仍然是按照标准位长来进行的,所以,即使我们加密一字节的明文,运算出来的结果也要按照标准位长来使用(当然了,除非我们能再采取措施区分真实的位长,一般不在考虑)。

    至于明文分片多次加密,自然密文长度成倍增长,但已不属于一次加密的问题,不能放到一起考虑。

    转载于:https://www.cnblogs.com/qiuxiangmuyu/p/6419957.html

    展开全文
  • 变大就变大吧,对于日常使用和APP开发或者服务端开发而言,大个几k字节是无所谓的,但是如果是使用RF(射频)通信,那么大几个字节就会导致通信失败率的增加,所以对于这样的场景,你就需要确保密文明文一样长,...

    加密之后会变大的问题

      做过加密的人都应该有“加密之后文件会变大”的经验。变大就变大吧,对于日常使用和APP开发或者服务端开发而言,大个几k字节是无所谓的,但是如果是使用RF(射频)通信,那么大几个字节就会导致通信失败率的增加,所以对于这样的场景,你就需要确保密文和明文一样长,最好是还能短一点。
      由于短一点是压缩算法的功劳,和加密算法本身没有关系,我们这里不做分析,今天我们以openssl的命令行工具为例来学习如何确保密文长度等于明文长度。

    为啥密文会比明文长

      为啥加密之后就会边长呢?为了更安全!那么为了更安全长到哪里了?
        1. 长在填充;
        2. 长在salt;
      填充主要是为了解决分组加密,明文长度不是分组的整数倍的问题,为了简化填充规则,如果明文是分组的倍数,就填充一个整的分组。
    如何确保明文和密文的长度是一致的
    上图就是一个明文是128bits的aes-128-cbc的加密样例,填充了整整一个128bits的填充块。
      salt是作为秘钥和IV生成的一个随机因子,为了解决相同的明文和秘钥生成相同的密文的问题,由于salt必须参与到运算中,所以salt通常是以明文的形式拼接在明文的最前面,salt通常是16个字节的长度,前8字节是个固定的magic数,后8个字节是随机数,这样有salt的密文至少会增加一个长度是16个字节的明文头部信息。
    如何确保明文和密文的长度是一致的
    上图就是一个有salt的,明文是一个字节的密文是16+1个字节的样例输出。

    如何控制让密文和明文长度一致呢

      既然增长是由于填充和salt导致的,那么要保证一样长,那就需要去掉填充和salt,当然去掉填充的前提需要明文的长度是分组的倍数,要不然加密会报错的。
    如何确保明文和密文的长度是一致的
    上图是一个nopad和nosalt的截图,我们在看一个对比图,如下:
    如何确保明文和密文的长度是一致的

    特别提醒小心-a的参数

      -a在参数在openssl里面是对加密或者解密结果的base64的处理,如果是加密就是base64编码,反之是解码。base64会把没3个字节编码为4个字节的科输入字符,如果不小心用到这个选项,你会发现密文长度填充了不少。
      重要的事情说三遍,用了-a会变长!用了-a会变长!用了-a会变长!

    进一步的学习资料推荐

      使用openssl做AES的加密
      使用openssl做SSL/TLS/HTTPS的实验

    转载于:https://blog.51cto.com/makofly/2122601

    展开全文
  • RSA 算法密钥长度的选择是安全性和程序性能平衡的结果,密钥长度越,安全性越好,加密解密所需时间越。 1、非对称加密算法中 1024bit 密钥的强度相当于对称加密算法 80bit 密钥的强度;   2、密钥长度增长一...
  • public static void main(String[] args) throws Exception { ... //============================================= 生成密文 System.out.println("密文:"+destCode.toString()); }
  • 提出了Simple Matrix方案的改进版本,通过使用具有随机二次多项式的可改变形式的...新的方案将密文与明文的比例改进为大于等于两倍,打破了固定不变的密文与明文比例,使其拥有一个灵活的明密文比,以适应不同的需求。
  • //输出密文(每次都不一样,更安全) echo '<Br><br>jia mi:::'.$ciphertext_base64 . "\n"; //解密: $ciphertext_dec = base64_decode($ciphertext_base64); $iv_dec = substr($ciphertext_dec, 0, $iv_size...
  • 所以我又把相同的明文又加了一边密发现我自己的加密密文跟对方demo里面的密文一样,连长度都差了很多,但是明文一样的。刚开始我用eclipse,发现我eclipse的编码格式是GBK,所以又改成用idea,把编码格式改成UTF...
  • 【什么叫明文,什么叫密文,为什么不允许在数据库里明文保存密码?】 每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析后端...
  • 在切换明文/密文的时候,如果切换前后的字符串宽度不一样,字符串末尾到光标之间会出现一大段空白。 解决办法: - (IBAction)secureButtonAction:(id)sender {  self.passwordTextField.secureTextEntry =
  • PBOC/EMV之脱机明文PIN和脱机密文PIN

    千次阅读 2014-01-13 15:50:23
    PBOC/EMV之脱机明文和脱机密文   1. EMVPBOC在脱机PIN的区别: EMV和PBOC都支持脱机明文PIN和联机密文PIN。区别在于EMV还支持脱机密文PIN,而在PBOC中,EMV标识支持脱机密文PIN的位置都成了保留位。 图1:PBOC中...
  • <p>input type="password" 在手机端表现为输入先显示明文然后一秒变密文,在web端则输入就是密文 是什么原因让input手机端和web端的表现不一样</p>
  • 因此,需要提供一种方式供用户查看自己输入的内容到底是什么。比如,密码框的右边有一个复选框,当勾选该复选框时就显示用户的输入(明文),否则显示为密码;或者,密码框的右侧有一个类似眼睛的图标,当鼠标停留在
  • 这里是修真院后端小课堂,每篇分享文从 【背景介绍】【知识剖析...【什么叫明文,什么叫密文,为什么不允许在数据库里明文保存密码?】 大家好,我是IT修真院深圳分院第10期的JAVA学员,一枚正直纯洁善良的java程...
  • 破译密文

    千次阅读 2014-03-18 17:55:53
    但在网络通信中,为了信息的安全性,常对明文进行加密,用密文进行传输。密文是由0、1和若干个密码字母组成,每个密码字母代表不超过100位不同的01串,例如,密文=011a0bf00a01。密码破译的关键是确定每个密码的含义...
  • AES加密方式是目前来看值得选择的加密方式,但是在Android中使用AES加密时,有些坑看似不大,却让很多人栽了跟头。...但是解决了那些大部分代码中存在的密文不唯一、解密不出明文的问题。AESCrypt.java中关键代码
  • 一、实验拓扑:明文认证:二、命令部署:R1(config)#int f0/0R1(config-if)#ip ospf authenticationR1(config-if)#ip ospf authentication-key 123 R2(config)#int f0/0R2(config-if)#ip ospf authenticationR2...
  • 2.不定输入定输出。不管你参与计算的数据多大,计算得出的乱码结果长度是固定的。他还有雪崩效应。非常相似的数据来做散列计算。他们两得出的结果,是完全不一样的。 帧尾fcs就是基于散列来做的,我给你做一个...
  • 备注:实际中会发现环回口无法网络正常连接,是因为子网掩码不一样,OSPF 路由器将环回口的网络类型认为是一种特殊的类型, LOOPBACK 类型。因此不管环回口前缀长度为多少,都一致认为其长度为 32。 因此,只需要...
  • pin密文是1.1+1.2 1+2=3,最后1和2进行二进制异或,3出表示07 和密码是什么后面异或 主密加密工密,工密加密密码 密码加密就好比,方程式,也可以说实一种投影,就是密码通过工作密码进行加密...
  • 如果仔细观察你会发现,不同的账号,使用相同的密码,最后生成的密文是不一样的 经过反编译标准产品的生成密码的代码,找到了生成密码的类:com.kingdee.bos.util.CryptoUtil 这个类有个静态方法public static ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,529
精华内容 7,011
关键字:

密文与明文一样长