程序员

RSA是什么?

2020-02-27  本文已影响0人  Cjiajiagame

不明白计算机的,就当看个热闹吧。
首先,我明确的指出,这是一种加密算法,不是你的摘要算法。而且,他虽然没有偏移量,但是他会产生两个密钥。不要再停在AES上了。
RSA,是一种已经被普及得非对称算法。度娘是这么说的:

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

现在大多数网站,尤其是含有敏感内容、重要内容得网站,往往在传输过程里使用RSA加密。不过要注意,它含有两个密钥,一个是加密用的私钥,一个是解密用得公钥。
RSA换成现实生活是什么呢?


首先,小明写了一封信,这封信说,小丽我们吃个饭吧。当然,这就是所谓的“隐私”,是需要加密的明文,如果将信直接给邮递小哥,说不定那时他就把你的信给劫走了,你的隐私就泄露了。怎么办?当然是“上锁”。
首先,把你的信装进一个箱子(加密对象)里,然后给他使用一把叫“私钥”的钥匙上锁,给快递小哥。当然。另一把钥匙不在他手里,他打不开。等待小哥将箱子送到小丽家时,先用一把叫“公钥”的钥匙解锁,打开箱子,这样小丽就可以看信了。
用计算机的语言来说的话,就是小明先生成钥匙对,把公钥传输给小丽,再将信用私钥加密成密文,通过网路传输给小丽。这时,小丽再使用小明发过来的公钥解密密文变成明文,这时小丽就可以看了。这就完成了一次安全的传输。


这种加密方式已经成为了网站的标配。唯一缺点就是非对称加密不能加密过长的文件,比如真实的正规的信就不能加密。
哈哈,程序员又来了。我今天再用java做一个实现方法!看热闹的可以阅读里面的注释,注释里就说明了原理以及上文的有趣科普!

package crypto.RSA;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import java.util.HashMap;
import java.util.Map;
import crypto.Exception.*;

/**
 * RSA加密。不乐意看的留个赞再走呗~
 */
public class RSA {
    private static final String CHARSET = "utf-8";
    private static final String ALGORITHM = "RSA";
    private static String str = null;
    private static String PublicKey = null, PrivateKey = null;
    public RSA(){}
    /**
     * 给你的明文套上箱子或者拿下箱子。只不过现在没有上锁也没有解锁。
     * @param STR 要给小丽的信
     * @param publicKey 公钥(解密用)
     * @param privateKey 私钥 (加密用)
     */
    public RSA(String STR, String publicKey, String privateKey){
        str = STR;
        PublicKey = publicKey;
        PrivateKey = privateKey;
    }

    /**
     * 创建一个钥匙对。公钥给小丽用来解密,私钥给自己用来加密。
     * @param keySize 秘钥的长度。应是64的倍数。
     * @return 带公钥和私钥Map->HashMap。
     * @throws NoSuchAlgorithmException
     * @throws KeyIvNotLengthyException
     */
    public final Map<String, String> createKeys(int keySize) throws NoSuchAlgorithmException,
            KeyIvNotLengthyException{
        if(keySize%64 != 0) throw new KeyIvNotLengthyException("秘钥长度应是64的倍数!");
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
        kpg.initialize(keySize);
        KeyPair keypair = kpg.generateKeyPair();
        Key publicKey = keypair.getPublic();
        String publicKeySTR = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
        Key privateKey = keypair.getPrivate();
        String privateKeySTR = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
        Map<String, String> map = new HashMap<>();
        map.put("publicKey", publicKeySTR);
        map.put("privateKey", privateKeySTR);
        return map;
    }
    private RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, 
            InvalidKeySpecException{
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }
    private RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, 
            InvalidKeySpecException{
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }

    /**
     * 小明给箱子上锁。
     * @return 正常则成功上锁,否则锁不上。
     * @throws NullKeyException
     * @throws KeyIvNotLengthyException
     * @throws Exception
     */
    public String Encrypt() throws NullKeyException,
            Exception{
        if(PrivateKey.length() == 0 || PrivateKey == null) throw new NullKeyException("私钥为空");
        RSAPrivateKey privateKey = getPrivateKey(PrivateKey);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return Base64.encodeBase64String(cipher.doFinal(str.getBytes()));
    }

    /**
     * 小丽给箱子解锁。
     * @return 正常则成功解锁,否则解不了。
     * @throws NullKeyException
     * @throws crypto.Exception.KeyIvNotLengthyException
     * @throws Exception
     */
    public String Decrypt() throws NullKeyException,
            Exception{
        if(PublicKey.length() == 0 || PublicKey == null) throw new NullKeyException("公钥为空");
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        byte[] encryptding = new Base64().decode(str.getBytes());
        RSAPublicKey publickey = getPublicKey(PublicKey);
        cipher.init(Cipher.DECRYPT_MODE, publickey);
        return new String(cipher.doFinal(encryptding));
    }
}

我这可是费了九牛二虎之力才整来的,因为很多实例都是与服务器有关的,并且java加密也不是很普及。我参考了好多大v的博客,然后自己再加上注释,最终再写一个GUI熟记……我发现只有电脑是玩着学会的,并且做爱好一点不累,做其他的却很累。
我就不在这墨迹了,要找详细的就去我更新的GITHUB上摸索去吧,有问题直接私信我就好。
听说点赞的人百毒不侵~~~

上一篇下一篇

猜你喜欢

热点阅读