公钥与私钥

摘要:
她写作后,使用张三的公钥进行加密,可以达到保密的效果。这里需要强调的是,只要不泄露张三的私钥,这封信是安全的,即使落入他人手中也无法解密。李思收到信后,取下数字签名,用张三的公钥解密,得到了信的摘要。这里,JWT令牌是通过非对称算法加密的,因此我们需要生成公钥和私钥。

在对称加密的时代,加密和解密用的是同一个密钥,这个密钥既用于加密,又用于解密。这样做有一个明显的缺点,如果两个人之间传输文件,两个人都要知道密钥,如果是三个人呢,五个人呢?于是就产生了非对称加密,用一个密钥进行加密(公钥),用另一个密钥进行解密(私钥)

1.公钥私钥原理

张三有两把钥匙,一把是公钥,另一把是私钥。

 公钥与私钥第1张

 张三把公钥送给他的朋友们—-李四、王五、赵六—-每人一把。

公钥与私钥第2张

 李四要给张三写一封保密的信。她写完后用张三的公钥加密,就可以达到保密的效果。

公钥与私钥第3张

 张三收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要张三的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

公钥与私钥第4张

 张三给李四回信,决定采用“数字签名”。他写完后先用Hash函数,生成信件的摘要(digest)。然后利用私钥将摘要进行加密,张三将这个签名,附在信件下面,一起发给李四。

公钥与私钥第5张

 李四收信后,取下数字签名,用张三的公钥解密,得到信件的摘要。由此证明,这封信确实是张三发出的。李四再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

公钥与私钥第6张

 2.生成私钥公钥

Spring Security 提供对JWT的支持,我们使用Spring Security 提供的JwtHelper来创建JWT令牌,校验JWT令牌 等操作。 这里JWT令牌我们采用非对称算法进行加密,所以我们要先生成公钥和私钥。

(1)生成密钥证书 下边命令生成密钥证书,采用RSA 算法每个证书包含公钥和私钥

创建一个文件夹,在该文件夹下执行如下命令行:

keytool 
-genkeypair 
-alias changgou 
-keyalg RSA 
-keypass changgou 
-keystore changgou.jks 
-storepass changgou 

Keytool 是一个java提供的证书管理工具

-alias:密钥的别名
-keyalg:使用的hash算法
-keypass:密钥的访问密码 
-keystore:密钥库文件名,xc.keystore保存了生成的证书 
-storepass:密钥库的访问密码

(2)查询证书信息

keytool -list -keystore changgou.jks

(3)删除别名

keytool -delete -alias changgou -keystore changgou.jsk

4.2.3 导出公钥

openssl是一个加解密工具包,这里使用openssl来导出公钥信息。

安装 openssl:http://slproweb.com/products/Win32OpenSSL.html

安装资料目录下的Win64OpenSSL-1_1_0g.exe

cmd进入changgou.jks文件所在目录执行如下命令(如下命令在windows下执行,会把-变成中文方式,请将它改成英文的-):

keytool -list -rfc --keystore changgou.jks | openssl x509 -inform pem -pubkey

公钥与私钥第7张

 将上边的公钥拷贝到文本public.key文件中,合并为一行,可以将它放到需要实现授权认证的工程中。

4.2.4 JWT令牌

(1)创建令牌数据

public class Test {
    public static void main(String[] args) {
        /**
         * 密钥证书文件路径
         */
        String key_location="changgou.jks";

        /**
         * 密钥库的访问密码
         */
        String key_password="changgou";

        /**
         * 密钥的访问密码
         */
        String keypwd = "changgou";

        /**
         * 秘钥别名
         */
        String alias = "changgou";

        /**
         * 访问证书路径
         */
        ClassPathResource resource = new ClassPathResource(key_location);
        /**
         * 创建秘钥工厂
         * 资源路径
         * 密钥库访问密码
         */
        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(resource,key_password.toCharArray());

        /**
         * 读取秘钥对(公钥、私钥)
         * 密钥别名
         * 密钥访问密码
         */
        KeyPair keyPair = keyStoreKeyFactory.getKeyPair(alias,keypwd.toCharArray());

        /**
         * 获取私钥
         */
        RSAPrivateKey rsaPrivate = (RSAPrivateKey) keyPair.getPrivate();

        /**
         * 定义Payload
         */
        Map<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("id", "1");
        tokenMap.put("name", "itheima");
        tokenMap.put("roles", "ROLE_VIP,ROLE_USER");

        /**
         * 生成jwt令牌
         * 用私钥加密
         */
        Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), new RsaSigner(rsaPrivate));

        /**
         * 取出令牌
         */
        String encoded = jwt.getEncoded();
        System.out.println(encoded);

    }
}

(2)解析令牌

上面创建令牌后,我们可以对JWT令牌进行解析,这里解析需要用到公钥,我们可以将之前生成的公钥public.key拷贝出来用字符串变量token存储,然后通过公钥解密。

public class Test2 {
    public static void main(String[] args) {
        /**
         * 令牌
         */
        String token ="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlcyI6IlJPTEVfVklQLFJPTEVfVVNFUiIsIm5hbWUiOiJpdGhlaW1hIiwiaWQiOiIxIn0.oW1h0Xza7vUEgi0rzOlgMLdLicnJ7kFXg6pBjW640sxzeeiPC0cUfXEYAAmmTYEMQtLeivbZeiar-p5ydupUVhTVF8evEzqt64p31DJQ5tsIQ2-moXE8Q6W9JP2MY1sylBdN8rmVmIW6pqBh4KuLkFFalWd851HAzdQg95SvIbyUu6F6M-iZvL4-qcTdakYjpnWKOTWNBighB-hMlaAs6REMXyMsU0wo8DRHyNypUb4vILb_NPjd69ubFhOTUvLkYRtImEk8QNnQ8-l68GhAGmqifxDkNAz3I0f0Mcgfu3OdT056qcR6FG_o1thzOaXRZQliA1B2ZnZ3tepHv6ahxw";

        /**
         * 使用公钥进行解密
         */
        String publickey ="-----BEGIN PUBLIC KEY-----
" +
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA15w2T+DOwQzFxWa26bFq
" +
                "1xhYdy49INE7vPC1D6+09P/c1byY6U7N3AStO3eYhT/v5TUwCfXobXZ98e2Gf1/O
" +
                "KO/TmLFXOcoea9MP0kVcVV/80O6g19tzWDIkBbphO9g5E0lq/VwQYC0Cc3/4jNO0
" +
                "87d5BwMdlSasqbJjA8MVDXjzupPDl+hw6Wr48motbJGgSzrOpNPZMJK25ylwlqac
" +
                "TCetcjQXL4tpKcPXOaCEUFwWWxBUtFfwP+nU0PSDTUhwe6UsKtugnkAd1TYn9+bh
" +
                "78J77CFwpFPxtfutSbP2E8/yxYKufUg6NYo+F3PRQQElTb/aH8zi4n+RIHvec2Zw
" +
                "HwIDAQAB
" +
                "-----END PUBLIC KEY-----";

        /**
         * 校验jwt
         */
        Jwt jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(publickey));


        /**
         * 获取Jwt原始内容
         */
        String claims = jwt.getClaims();
        System.out.println(claims);
    }
}

免责声明:文章转载自《公钥与私钥》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js 创建音频声音一个简单的MySQL数据库同步脚本下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Eclipse paho学习笔记

Eclipse Paho java 支持java和android 两个客户端异步和同步, MqttAsyncClient,MqttClient 其中 后者是前者的包装同步器,特效除了5.0都支持 有两个版本可以相互替换 <dependency> <groupId>org.eclipse.paho</...

浅淡Webservice、WSDL三种服务访问的方式(附案例)

Webservice Webservice是使应用程序以与平台和编程语言无关的方式进行相互通信技术。 eg:站点提供访问的数据接口:新浪微博、淘宝。 官方解释:它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行;它是一种新的web应用程序分支,是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。WebService是一个...

okhttp同步异步下载文件,与http请求工具类

<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>4.8.0</ve...

EF core的原生SQL查询以及用EF core进行分页查询遇到的问题

在用.net core进行数据库访问,需要处理一些比较复杂的查询,就不得不用原生的SQL查询了,然而EF Core 和EF6 的原生sql查询存在很大的差异。 在EF6中我们用SqlQuery和ExecuteSqlCommand进行sql语句的执行,而在EF Core中我们则使用FromSql和ExecuteSqlCommand 一.ExecuteSqlC...

公众号第三方平台开发 component_verify_ticket和accessToken的获取

公众号第三方平台审核通过之后,微信的服务器会定时(10分钟一次)给"授权事件接收URL"发送component_verify_ticket,这里我们需要及时更新component_verify_ticket 就是下面这个链接 下面这里是我的处理函数 private void ResponseRequest() { //WX...

基于Platinum库的DMS实现(android)

接上篇博文:基于Platinum库的DMR实现(android) 文章讲述了如何使用Platinum库实现DMR 今天同样使用该库,来讲解一下DMS的实现 关于该库如何编译,请参考这篇博文:NDK下 将Platinum SDK 编译成so库 (android - upnp) 下面给出运行效果图: 界面很简单,就是一些开关和设备名以及设备运行状态的展现 下...