本文出处:http://blog.csdn.net/chaijunkun/article/details/7275632,转载请注明。由于本人不定期会整理相关博文,会对相应内容作出完善。因此强烈建议在原始出处查看此文。


RSA是什么:RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。目前该加密方式广泛用于网上银行、数字签名等场合。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

OpenSSL是什么:众多的密码算法、公钥基础设施标准以及SSL协议,或许这些有趣的功能会让你产生实现所有这些算法和标准的想法。果真如此,在对你表示敬佩的同时,还是忍不住提醒你:这是一个令人望而生畏的过程。这个工作不再是简单的读懂几本密码学专著和协议文档那么简单,而是要理解所有这些算法、标准和协议文档的每一个细节,并用你可能很熟悉的C语言字符一个一个去实现这些定义和过程。我们不知道你将需要多少时间来完成这项有趣而可怕的工作,但肯定不是一年两年的问题。OpenSSL就是由Eric A. Young和Tim J. Hudson两位绝世大好人自1995年就开始编写的集合众多安全算法的算法集合。通过命令或者开发库,我们可以轻松实现标准的公开算法应用。


我的一个假设应用背景:

随着移动互联网的普及,为移动设备开发的应用也层出不穷。这些应用往往伴随着用户注册与密码验证的功能。”网络传输“、”应用程序日志访问“中的安全性都存在着隐患。密码作为用户的敏感数据,特别需要开发者在应用上线之前做好安全防范。处理不当,可能会造成诸如商业竞争对手的恶意攻击、第三方合作商的诉讼等问题。


RSA算法虽然有这么多好处,但是在网上找不到一个完整的例子来说明如何操作。下面我就来介绍一下:

一、使用OpenSSL来生成私钥和公钥

我使用的是Linux系统,已经安装了OpenSSL软件包,此时请验证你的机器上已经安装了OpenSSL,运行命令应当出现如下信息:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# openssl version -a  
  2. OpenSSL 1.0.0-fips 29 Mar 2010  
  3. built on: Wed Jan 25 02:17:15 GMT 2012  
  4. platform: linux-x86_64  
  5. options:  bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)   
  6. compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DWHIRLPOOL_ASM  
  7. OPENSSLDIR: "/etc/pki/tls"  
  8. engines:  aesni dynamic   

先来生成私钥:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# openssl genrsa -out rsa_private_key.pem 1024  
  2. Generating RSA private key, 1024 bit long modulus  
  3. .......................++++++  
  4. ..++++++  
  5. e is 65537 (0x10001)  
这条命令让openssl随机生成了一份私钥,加密长度是1024位。加密长度是指理论上最大允许”被加密的信息“长度的限制,也就是明文的长度限制。随着这个参数的增大(比方说2048),允许的明文长度也会增加,但同时也会造成计算复杂度的极速增长。一般推荐的长度就是1024位(128字节)。

我们来看一下私钥的内容:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# cat rsa_private_key.pem   
  2. -----BEGIN RSA PRIVATE KEY-----  
  3. MIICWwIBAAKBgQChDzcjw/rWgFwnxunbKp7/4e8w/UmXx2jk6qEEn69t6N2R1i/L  
  4. mcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRhtVx1uOH/2U378fscEESEG8XDq  
  5. ll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNgXIlk3gdhnzh+uoEQywIDAQAB  
  6. AoGAaeKk76CSsp7k90mwyWP18GhLZru+vEhfT9BpV67cGLg1owFbntFYQSPVsTFm  
  7. U2lWn5HD/IcV+EGaj4fOLXdM43Kt4wyznoABSZCKKxs6uRciu8nQaFNUy4xVeOfX  
  8. PHU2TE7vi4LDkw9df1fya+DScSLnaDAUN3OHB5jqGL+Ls5ECQQDUfuxXN3uqGYKk  
  9. znrKj0j6pY27HRfROMeHgxbjnnApCQ71SzjqAM77R3wIlKfh935OIV0aQC4jQRB4  
  10. iHYSLl9lAkEAwgh4jxxXeIAufMsgjOi3qpJqGvumKX0W96McpCwV3Fsew7W1/msi  
  11. suTkJp5BBvjFvFwfMAHYlJdP7W+nEBWkbwJAYbz/eB5NAzA4pxVR5VmCd8cuKaJ4  
  12. EgPLwsjI/mkhrb484xZ2VyuICIwYwNmfXpA3yDgQWsKqdgy3Rrl9lV8/AQJAcjLi  
  13. IfigUr++nJxA8C4Xy0CZSoBJ76k710wdE1MPGr5WgQF1t+P+bCPjVAdYZm4Mkyv0  
  14. /yBXBD16QVixjvnt6QJABli6Zx9GYRWnu6AKpDAHd8QjWOnnNfNLQHue4WepEvkm  
  15. CysG+IBs2GgsXNtrzLWJLFx7VHmpqNTTC8yNmX1KFw==  
  16. -----END RSA PRIVATE KEY-----  

内容都是标准的ASCII字符,开头一行和结尾一行有明显的标记,真正的私钥数据是中间的不规则字符。

2015年3月24日补充:密钥文件最终将数据通过Base64编码进行存储。可以看到上述密钥文件内容每一行的长度都很规律。这是由于RFC2045中规定:The encoded output stream must be represented in lines of no more than 76 characters each。也就是说Base64编码的数据每行最多不超过76字符,对于超长数据需要按行分割。

接下来根据私钥生成公钥:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout  
  2. writing RSA key  
再来看一下公钥的内容:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# cat rsa_public_ley.pem   
  2. -----BEGIN PUBLIC KEY-----  
  3. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChDzcjw/rWgFwnxunbKp7/4e8w  
  4. /UmXx2jk6qEEn69t6N2R1i/LmcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRht  
  5. Vx1uOH/2U378fscEESEG8XDqll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNg  
  6. XIlk3gdhnzh+uoEQywIDAQAB  
  7. -----END PUBLIC KEY-----  
这时候的私钥还不能直接被使用,需要进行PKCS#8编码

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt  
命令中指明了输入私钥文件为rsa_private_key.pem,输出私钥文件为pkcs8_rsa_private_key.pem,不采用任何二次加密(-nocrypt)

再来看一下,编码后的私钥文件是不是和之前的私钥文件不同了:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@chaijunkun ~]# cat pkcs8_rsa_private_key.pem   
  2. -----BEGIN PRIVATE KEY-----  
  3. MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG  
  4. 6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4  
  5. 1rCLtolpGG1XHW44f/ZTfvx+xwQRIQbxcOqWXQYJ8HX9OMojZqK1VLNc61GzyRiA  
  6. ZTvx/tWYM2BciWTeB2GfOH66gRDLAgMBAAECgYBp4qTvoJKynuT3SbDJY/XwaEtm  
  7. u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j  
  8. DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo  
  9. MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ  
  10. DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM  
  11. 6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ  
  12. FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA  
  13. 2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX  
  14. TB0TUw8avlaBAXW34/5sI+NUB1hmbgyTK/T/IFcEPXpBWLGO+e3pAkAGWLpnH0Zh  
  15. Fae7oAqkMAd3xCNY6ec180tAe57hZ6kS+SYLKwb4gGzYaCxc22vMtYksXHtUeamo  
  16. 1NMLzI2ZfUoX  
  17. -----END PRIVATE KEY-----  

至此,可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem。

2014年5月20日补充:最近又遇到RSA加密的需求了,而且对方要求只能使用第一步生成的未经过PKCS#8编码的私钥文件。后来查看相关文献得知第一步生成的私钥文件编码是PKCS#1格式,这种格式Java其实是支持的,只不过多写两行代码而已:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(priKeyData));  
  2. RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());  
  3. KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
  4. PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec);  
首先将PKCS#1的私钥文件读取出来(注意去掉减号开头的注释内容),然后使用Base64解码读出的字符串,便得到priKeyData,也就是第一行代码中的参数。最后一行得到了私钥。接下来的用法就没什么区别了。

参考文献:https://community.oracle.com/thread/1529240?start=0&tstart=0


二、编写Java代码实际测试

2012年2月23日补充:在标准JDK中只是规定了JCE(JCE (Java Cryptography Extension) 是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。)接口,但是内部实现需要自己或者第三方提供。因此我们这里使用bouncycastle的开源的JCE实现包,下载地址:http://bouncycastle.org/latest_releases.html,我使用的是bcprov-jdk16-146.jar,这是在JDK1.6环境下使用的。如果需要其他JDK版本下的实现,可以在之前的下载页面中找到对应版本。

下面来看一下我实现的代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package net.csdn.blog.chaijunkun;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.security.InvalidKeyException;  
  8. import java.security.KeyFactory;  
  9. import java.security.KeyPair;  
  10. import java.security.KeyPairGenerator;  
  11. import java.security.NoSuchAlgorithmException;  
  12. import java.security.SecureRandom;  
  13. import java.security.interfaces.RSAPrivateKey;  
  14. import java.security.interfaces.RSAPublicKey;  
  15. import java.security.spec.InvalidKeySpecException;  
  16. import java.security.spec.PKCS8EncodedKeySpec;  
  17. import java.security.spec.X509EncodedKeySpec;  
  18.   
  19. import javax.crypto.BadPaddingException;  
  20. import javax.crypto.Cipher;  
  21. import javax.crypto.IllegalBlockSizeException;  
  22. import javax.crypto.NoSuchPaddingException;  
  23.   
  24. import org.bouncycastle.jce.provider.BouncyCastleProvider;  
  25.   
  26. import sun.misc.BASE64Decoder;  
  27.   
  28. public class RSAEncrypt {  
  29.       
  30.     private static final String DEFAULT_PUBLIC_KEY=   
  31.         "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChDzcjw/rWgFwnxunbKp7/4e8w" + "\r" +  
  32.         "/UmXx2jk6qEEn69t6N2R1i/LmcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRht" + "\r" +  
  33.         "Vx1uOH/2U378fscEESEG8XDqll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNg" + "\r" +  
  34.         "XIlk3gdhnzh+uoEQywIDAQAB" + "\r";  
  35.       
  36.     private static final String DEFAULT_PRIVATE_KEY=  
  37.         "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG" + "\r" +  
  38.         "6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4" + "\r" +  
  39.         "1rCLtolpGG1XHW44f/ZTfvx+xwQRIQbxcOqWXQYJ8HX9OMojZqK1VLNc61GzyRiA" + "\r" +  
  40.         "ZTvx/tWYM2BciWTeB2GfOH66gRDLAgMBAAECgYBp4qTvoJKynuT3SbDJY/XwaEtm" + "\r" +  
  41.         "u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j" + "\r" +  
  42.         "DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo" + "\r" +  
  43.         "MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ" + "\r" +  
  44.         "DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM" + "\r" +  
  45.         "6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ" + "\r" +  
  46.         "FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "\r" +  
  47.         "2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "\r" +  
  48.         "TB0TUw8avlaBAXW34/5sI+NUB1hmbgyTK/T/IFcEPXpBWLGO+e3pAkAGWLpnH0Zh" + "\r" +  
  49.         "Fae7oAqkMAd3xCNY6ec180tAe57hZ6kS+SYLKwb4gGzYaCxc22vMtYksXHtUeamo" + "\r" +  
  50.         "1NMLzI2ZfUoX" + "\r";  
  51.   
  52.     /** 
  53.      * 私钥 
  54.      */  
  55.     private RSAPrivateKey privateKey;  
  56.   
  57.     /** 
  58.      * 公钥 
  59.      */  
  60.     private RSAPublicKey publicKey;  
  61.       
  62.     /** 
  63.      * 字节数据转字符串专用集合 
  64.      */  
  65.     private static final char[] HEX_CHAR= {'0''1''2''3''4''5''6''7''8''9''a''b''c''d''e''f'};  
  66.       
  67.   
  68.     /** 
  69.      * 获取私钥 
  70.      * @return 当前的私钥对象 
  71.      */  
  72.     public RSAPrivateKey getPrivateKey() {  
  73.         return privateKey;  
  74.     }  
  75.   
  76.     /** 
  77.      * 获取公钥 
  78.      * @return 当前的公钥对象 
  79.      */  
  80.     public RSAPublicKey getPublicKey() {  
  81.         return publicKey;  
  82.     }  
  83.   
  84.     /** 
  85.      * 随机生成密钥对 
  86.      */  
  87.     public void genKeyPair(){  
  88.         KeyPairGenerator keyPairGen= null;  
  89.         try {  
  90.             keyPairGen= KeyPairGenerator.getInstance("RSA");  
  91.         } catch (NoSuchAlgorithmException e) {  
  92.             e.printStackTrace();  
  93.         }  
  94.         keyPairGen.initialize(1024new SecureRandom());  
  95.         KeyPair keyPair= keyPairGen.generateKeyPair();  
  96.         this.privateKey= (RSAPrivateKey) keyPair.getPrivate();  
  97.         this.publicKey= (RSAPublicKey) keyPair.getPublic();  
  98.     }  
  99.   
  100.     /** 
  101.      * 从文件中输入流中加载公钥 
  102.      * @param in 公钥输入流 
  103.      * @throws Exception 加载公钥时产生的异常 
  104.      */  
  105.     public void loadPublicKey(InputStream in) throws Exception{  
  106.         try {  
  107.             BufferedReader br= new BufferedReader(new InputStreamReader(in));  
  108.             String readLine= null;  
  109.             StringBuilder sb= new StringBuilder();  
  110.             while((readLine= br.readLine())!=null){  
  111.                 if(readLine.charAt(0)=='-'){  
  112.                     continue;  
  113.                 }else{  
  114.                     sb.append(readLine);  
  115.                     sb.append('\r');  
  116.                 }  
  117.             }  
  118.             loadPublicKey(sb.toString());  
  119.         } catch (IOException e) {  
  120.             throw new Exception("公钥数据流读取错误");  
  121.         } catch (NullPointerException e) {  
  122.             throw new Exception("公钥输入流为空");  
  123.         }  
  124.     }  
  125.   
  126.   
  127.     /** 
  128.      * 从字符串中加载公钥 
  129.      * @param publicKeyStr 公钥数据字符串 
  130.      * @throws Exception 加载公钥时产生的异常 
  131.      */  
  132.     public void loadPublicKey(String publicKeyStr) throws Exception{  
  133.         try {  
  134.             BASE64Decoder base64Decoder= new BASE64Decoder();  
  135.             byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);  
  136.             KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
  137.             X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);  
  138.             this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);  
  139.         } catch (NoSuchAlgorithmException e) {  
  140.             throw new Exception("无此算法");  
  141.         } catch (InvalidKeySpecException e) {  
  142.             throw new Exception("公钥非法");  
  143.         } catch (IOException e) {  
  144.             throw new Exception("公钥数据内容读取错误");  
  145.         } catch (NullPointerException e) {  
  146.             throw new Exception("公钥数据为空");  
  147.         }  
  148.     }  
  149.   
  150.     /** 
  151.      * 从文件中加载私钥 
  152.      * @param keyFileName 私钥文件名 
  153.      * @return 是否成功 
  154.      * @throws Exception  
  155.      */  
  156.     public void loadPrivateKey(InputStream in) throws Exception{  
  157.         try {  
  158.             BufferedReader br= new BufferedReader(new InputStreamReader(in));  
  159.             String readLine= null;  
  160.             StringBuilder sb= new StringBuilder();  
  161.             while((readLine= br.readLine())!=null){  
  162.                 if(readLine.charAt(0)=='-'){  
  163.                     continue;  
  164.                 }else{  
  165.                     sb.append(readLine);  
  166.                     sb.append('\r');  
  167.                 }  
  168.             }  
  169.             loadPrivateKey(sb.toString());  
  170.         } catch (IOException e) {  
  171.             throw new Exception("私钥数据读取错误");  
  172.         } catch (NullPointerException e) {  
  173.             throw new Exception("私钥输入流为空");  
  174.         }  
  175.     }  
  176.   
  177.     public void loadPrivateKey(String privateKeyStr) throws Exception{  
  178.         try {  
  179.             BASE64Decoder base64Decoder= new BASE64Decoder();  
  180.             byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);  
  181.             PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);  
  182.             KeyFactory keyFactory= KeyFactory.getInstance("RSA");  
  183.             this.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);  
  184.         } catch (NoSuchAlgorithmException e) {  
  185.             throw new Exception("无此算法");  
  186.         } catch (InvalidKeySpecException e) {  
  187.             throw new Exception("私钥非法");  
  188.         } catch (IOException e) {  
  189.             throw new Exception("私钥数据内容读取错误");  
  190.         } catch (NullPointerException e) {  
  191.             throw new Exception("私钥数据为空");  
  192.         }  
  193.     }  
  194.   
  195.     /** 
  196.      * 加密过程 
  197.      * @param publicKey 公钥 
  198.      * @param plainTextData 明文数据 
  199.      * @return 
  200.      * @throws Exception 加密过程中的异常信息 
  201.      */  
  202.     public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{  
  203.         if(publicKey== null){  
  204.             throw new Exception("加密公钥为空, 请设置");  
  205.         }  
  206.         Cipher cipher= null;  
  207.         try {  
  208.             cipher= Cipher.getInstance("RSA"new BouncyCastleProvider());  
  209.             cipher.init(Cipher.ENCRYPT_MODE, publicKey);  
  210.             byte[] output= cipher.doFinal(plainTextData);  
  211.             return output;  
  212.         } catch (NoSuchAlgorithmException e) {  
  213.             throw new Exception("无此加密算法");  
  214.         } catch (NoSuchPaddingException e) {  
  215.             e.printStackTrace();  
  216.             return null;  
  217.         }catch (InvalidKeyException e) {  
  218.             throw new Exception("加密公钥非法,请检查");  
  219.         } catch (IllegalBlockSizeException e) {  
  220.             throw new Exception("明文长度非法");  
  221.         } catch (BadPaddingException e) {  
  222.             throw new Exception("明文数据已损坏");  
  223.         }  
  224.     }  
  225.   
  226.     /** 
  227.      * 解密过程 
  228.      * @param privateKey 私钥 
  229.      * @param cipherData 密文数据 
  230.      * @return 明文 
  231.      * @throws Exception 解密过程中的异常信息 
  232.      */  
  233.     public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{  
  234.         if (privateKey== null){  
  235.             throw new Exception("解密私钥为空, 请设置");  
  236.         }  
  237.         Cipher cipher= null;  
  238.         try {  
  239.             cipher= Cipher.getInstance("RSA"new BouncyCastleProvider());  
  240.             cipher.init(Cipher.DECRYPT_MODE, privateKey);  
  241.             byte[] output= cipher.doFinal(cipherData);  
  242.             return output;  
  243.         } catch (NoSuchAlgorithmException e) {  
  244.             throw new Exception("无此解密算法");  
  245.         } catch (NoSuchPaddingException e) {  
  246.             e.printStackTrace();  
  247.             return null;  
  248.         }catch (InvalidKeyException e) {  
  249.             throw new Exception("解密私钥非法,请检查");  
  250.         } catch (IllegalBlockSizeException e) {  
  251.             throw new Exception("密文长度非法");  
  252.         } catch (BadPaddingException e) {  
  253.             throw new Exception("密文数据已损坏");  
  254.         }         
  255.     }  
  256.   
  257.       
  258.     /** 
  259.      * 字节数据转十六进制字符串 
  260.      * @param data 输入数据 
  261.      * @return 十六进制内容 
  262.      */  
  263.     public static String byteArrayToString(byte[] data){  
  264.         StringBuilder stringBuilder= new StringBuilder();  
  265.         for (int i=0; i<data.length; i++){  
  266.             //取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移  
  267.             stringBuilder.append(HEX_CHAR[(data[i] & 0xf0)>>> 4]);  
  268.             //取出字节的低四位 作为索引得到相应的十六进制标识符  
  269.             stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);  
  270.             if (i<data.length-1){  
  271.                 stringBuilder.append(' ');  
  272.             }  
  273.         }  
  274.         return stringBuilder.toString();  
  275.     }  
  276.   
  277.   
  278.     public static void main(String[] args){  
  279.         RSAEncrypt rsaEncrypt= new RSAEncrypt();  
  280.         //rsaEncrypt.genKeyPair();  
  281.   
  282.         //加载公钥  
  283.         try {  
  284.             rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);  
  285.             System.out.println("加载公钥成功");  
  286.         } catch (Exception e) {  
  287.             System.err.println(e.getMessage());  
  288.             System.err.println("加载公钥失败");  
  289.         }  
  290.   
  291.         //加载私钥  
  292.         try {  
  293.             rsaEncrypt.loadPrivateKey(RSAEncrypt.DEFAULT_PRIVATE_KEY);  
  294.             System.out.println("加载私钥成功");  
  295.         } catch (Exception e) {  
  296.             System.err.println(e.getMessage());  
  297.             System.err.println("加载私钥失败");  
  298.         }  
  299.   
  300.         //测试字符串  
  301.         String encryptStr= "Test String chaijunkun";  
  302.   
  303.         try {  
  304.             //加密  
  305.             byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());  
  306.             //解密  
  307.             byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);  
  308.             System.out.println("密文长度:"+ cipher.length);  
  309.             System.out.println(RSAEncrypt.byteArrayToString(cipher));  
  310.             System.out.println("明文长度:"+ plainText.length);  
  311.             System.out.println(RSAEncrypt.byteArrayToString(plainText));  
  312.             System.out.println(new String(plainText));  
  313.         } catch (Exception e) {  
  314.             System.err.println(e.getMessage());  
  315.         }  
  316.     }  
  317. }  

代码中我提供了两种加载公钥和私钥的方式。

按流来读取:适合在android应用中按ID索引资源得到InputStream的方式;

按字符串来读取:就像代码中展示的那样,将密钥内容按行存储到静态常量中,按String类型导入密钥。


运行上面的代码,会显示如下信息:

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. 加载公钥成功  
  2. 加载私钥成功  
  3. 密文长度:128  
  4. 35 b4 6f 49 69 ae a3 85 a2 a5 0d 45 75 00 23 23 e6 70 69 b4 59 ae 72 6f 6d d3 43 e1 d3 44 85 eb 04 57 2c 46 3e 70 09 4d e6 4c 83 50 c7 56 75 80 c7 e1 31 64 57 c8 e3 46 a7 ce 57 31 ac cd 21 89 89 8f c1 24 c1 22 0c cb 70 6a 0d fa c9 38 80 ba 2e e1 29 02 ed 45 9e 88 e9 23 09 87 af ad ab ac cb 61 03 3c a1 81 56 a5 de c4 79 aa 3e 48 ee 30 3d bc 5b 47 50 75 9f fd 22 87 9e de b1 f4 e8 b2  
  5. 明文长度:22  
  6. 54 65 73 74 20 53 74 72 69 6e 67 20 63 68 61 69 6a 75 6e 6b 75 6e  
  7. Test String chaijunkun  

在main函数中我注释掉了”rsaEncrypt.genKeyPair()“,这个方法是用来随机生成密钥对的(只生成、使用,不存储)。当不使用文件密钥时,可以将载入密钥的代码注释,启用本方法,也可以跑通代码。

加载公钥与加载私钥的不同点在于公钥加载时使用的是X509EncodedKeySpec(X509编码的Key指令),私钥加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。


2012年2月22日补充:在android软件开发的过程中,发现上述代码不能正常工作,主要原因在于sun.misc.BASE64Decoder类在android开发包中不存在。因此需要特别在网上寻找rt.jar的源代码,至于JDK的src.zip中的源代码,这个只是JDK中的部分源代码,上述的几个类的代码都没有。经过寻找并添加,上述代码在android应用中能够很好地工作。其中就包含这个类的对应代码。另外此类还依赖于CEFormatException、CEStreamExhausted、CharacterDecoder和CharacterEncoder类和异常定义。


2012年2月23日补充:起初,我写这篇文章是想不依赖于任何第三方包来实现RSA的加密与解密,然而后续遇到了问题。由于在加密方法encrypt和解密方法decrypt中都要建立一个Cipher对象,这个对象只能通过getInstance来获取实例。它有两种:第一个是只指定算法,不指定提供者Provider的;第二个是两个都要指定的。起初没有指定,代码依然能够跑通,但是你会发现,每次加密的结果都不一样。后来分析才知道Cipher对象使用的公私钥是内部自己随机生成的,不是代码中指定的公私钥。奇怪的是,这种不指定Provider的代码能够在android应用中跑通,而且每次加密的结果都相同。我想,android的SDK中除了系统的一些开发函数外,自己也实现了JDK的功能,可能在它自己的JDK中已经提供了相应的Provider,才使得每次加密结果相同。当我像网上的示例代码那样加入了bouncycastle的Provider后,果然每次加密的结果都相同了。


参考文献:

RSA介绍:http://baike.baidu.com/view/7520.htm

OpenSSL介绍:http://baike.baidu.com/view/300712.htm

密钥对生成:http://www.howforge.com/how-to-generate-key-pair-using-openssl

私钥编码格式转换:http://shuany.iteye.com/blog/730910

JCE介绍:http://baike.baidu.com/view/1855103.htm

版权声明:本文为博主原创文章,未经博主允许不得转载。

16
1
主题推荐
java rsa ssl c语言 数据 openssl 麻省理工学院
猜你在找
JDBC视频教程
Cocos2d-Lua手游开发基础篇
Java Swing、JDBC开发桌面级应用
R语言知识体系概览
.NET平台和C#编程从入门到精通
准备好了么? 更多职位尽在 
中级Java开发(南昌)-数据软件
北京合力亿捷科技股份有限公司
4-8K/月
我要跳槽
数据挖掘Java工程师
云盛海宏信息技术(深圳)有限公司
10-20K/月
我要跳槽
java研发工程师(金融大数据)
百度在线网络技术(北京)有限公司
16-30K/月
我要跳槽
java开发工程师(数据抓取)
百猎网
25-35K/月
我要跳槽
src="http://blog.csdn.net/common/ad.html?t=4&containerId=ad_cen&frmId=ad_frm_0" style="border-width: 0px; overflow: hidden; width: 988px; height: 90px;" scrolling="no" id="ad_frm_0" frameborder="0">
查看评论
25楼 sinat_30047989 2015-07-23 09:37发表 [回复]
我这边用您的代码在android端把加密后的数据用Base64编码成字符串后经过网络传递到java端后,java端先用Base64解密,然后再用私钥解密会报java.lang.Exception: 密文数据已损坏的错误,楼主知道怎么处理吗?
Re: JackCousins 5天前 18:43发表 [回复]
回复sinat_30047989:首先能否调通各自的加解密?例如android自己和服务器自己能否实现加解密?其次再看下服务器端读取密文的长度。如果您采用的是2048位加密,数据分片应为256字节。多了或者少了都会抛出数据损坏异常
24楼 landerson 2015-07-20 17:47发表 [回复]
老大,有整过python用私匙加密,然后在安卓里用公匙解密不?
搞了老大天,解出来都是乱码。已经是有PKCS1
Re: JackCousins 5天前 18:40发表 [回复]
回复landerson:Python我不熟悉,您说的我没有做过
23楼 陨落烟雨 2015-07-08 11:00发表 [回复]
class "org.bouncycastle.asn1.ASN1ObjectIdentifier"'s signer information does not match signer information of other classes in the same package
楼主请问这个是什么导致的!
Re: JackCousins 2015-07-09 08:43发表 [回复]
回复AniuLincion:根据提示应该是类org.bouncycastle.asn1.ASN1ObjectIdentifier签名错误的问题。尝试重新下载bouncycastle的Provider包或者查看pom配置中是否还引入了其它版本的包
22楼 天莫邪 2015-03-12 17:00发表 [回复]
正在做RSA,C#服务器和android交互加密解密。谢谢楼主分享。
21楼 playboykpk 2015-02-13 22:50发表 [回复]
大神你好,请教一下,不知道为什么我的公钥给安卓客户端可以使用,但是给IOS客户端就无法加密,网上好像有说是IOS使用的编码格式不一样,但是一直找不到解决的办法,不知道你对这块有没有研究,谢谢!
Re: JackCousins 2015-02-16 18:08发表 [回复]
回复playboykpk:对IOS的API不了解,不过查询的几个关键词无非就是PKCS#1,RSA之类的。翻墙谷歌找找吧,Sorry,没能帮到你
20楼 AwayNeverComeBack 2014-11-11 16:52发表 [回复]
大哥您好,我用java产生的钥匙给IOS端加密,返回后我用私钥解乱码,去掉解密方法中的new BouncyCastleProvider()后会出现密文以损坏,求解,谢谢大哥
Re: JackCousins 2014-11-12 10:01发表 [回复]
回复AwayNeverComeBack:在解密时第一句话Cipher.getInstance("RSA", ....中,第一个参数用来指定算法,你可以试试将参数改为RSA/BCB/PKCS1Padding,看能否解密成功
Re: AwayNeverComeBack 2014-11-12 10:57发表 [回复]
回复chaijunkun:谢谢大哥,但是还是不行,改成NONE,或者ECB都不行,密文数据以损坏,IOS端和这边匹配,昨天实验只有一对钥匙好用,除了那一对就都不行。。。麻烦大哥了
19楼 zhangke19891001 2014-10-31 15:02发表 [回复]
大哥你好,最近遇到了一个RSA加密的问题,我做android客户端,服务器要求客户端发送密码时密码用RSA加密并且RSA_PKCS1_PADDING填充,并将加密的结果base64编码,我试了好多方法都不行,从服务器返回的数据一直是解密错误,麻烦问一下这是怎么回事,我菜鸟新手,谢谢大哥了
Re: JackCousins 2014-10-31 20:15发表 [回复]
回复zhangke19891001:PKCS#1编码的私钥加解密需要原始数据的对齐字节值为11。举个例子,假设密钥长度是2048位,即256字节,由于使用PKCS#1,因此每次加密数据的最大长度为256-11=245字节,加密后数据长度仍然为256字节。不知道这个问题你注意到了没
Re: zhangke19891001 2014-11-03 10:17发表 [回复]
回复chaijunkun:大哥,有没有可能是服务器端和客户端的base64编码不一样?
Re: JackCousins 2014-11-03 14:53发表 [回复]
回复zhangke19891001:base64是公开算法,只要原始数据一样,编码后的结果也是一样的。首先你确定服务器端是用Java写的吗?如果是,用的base64是apache的codec组件吗?如果是你公司自己开发的服务器和客户端,可以跟后端组协商,首先后端能否完成加密和解密双向操作,如果可以,你申请把公钥和私钥都拿到,在安卓设备上自己做加解密,如果你这边也能双向操作再进行联调。另外注意引用bouncy castle的安全包
Re: zhangke19891001 2014-11-03 15:54发表 [回复]
回复chaijunkun:大哥,我们服务器用的是C++做得,公钥和私钥我都能拿到,请问如果我在android这边可以实现加密和解密,请问如何联调,谢谢大哥
Re: JackCousins 2014-11-04 10:01发表 [回复]
回复zhangke19891001:这样的话先约定一个明文数据(例如:abc123)让服务端记录下加密后的密文原始十六进制和Base64编码之后的数据,然后你将Base64编码后的数据解码,看结果和密文十六进制数据是否一致。如果一致就说明Base64没有问题。然后用相同的密钥在你那边加密同样的明文数据,看十六进制是否一致。将你生成的密文交给服务器,看对方是否能解开。反正要一点点定位问题。
Re: zhangke19891001 2014-11-03 09:57发表 [回复]
回复chaijunkun:大哥您好,我的公钥长度是1024,您上面文章写的这几行代码和我这个问题有关吗,
RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence)

ASN1Sequence.fromByteArray(priKeyData));
RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(),
asn1PrivKey.getPrivateExponent());
还有,能不能请大哥帮我看看我的这个问题,我都困在这个问题好几天了,实在没办法了,谢谢大哥了
Re: zhangke19891001 2014-11-04 15:23发表 [回复]
回复zhangke19891001:大哥,服务器的私钥是C++用openssl生成的,格式是您上面文章写的未经PKCS#8编码的那种格式,也就是您说的PKCS#1格式,而且是RSA_PKCS1_PADDING填充, 那我客户端java应该如何加密才能让服务器顺利解密?
18楼 天地一蟲 2014-09-17 17:30发表 [回复]
楼主您好!阅读了您的文章,受益匪浅,但是我在做签名过程中,出现了如下错误:DERApplicationSpecific cannot be cast to ASN1Sequence
不知您有没有遇到过同样的情况,我初步怀疑是版本的问题,不知道您处理pkcs#1格式的私钥时,用的是什么版本的jar文件?
我使用的是jdk1.7和bcprov-jdk16-1.46.jar,jdk1.6也使用过,但是没法解决这个问题。望楼主指定一二,十分感谢!
Re: JackCousins 2014-09-18 09:45发表 [回复]
回复charlie555:你是不是做类型强转了才会抛这个异常呀?建议你弄清楚密钥是怎么生成到,如果是用openssl命令生成的,要知道生成的编码格式是哪一种。
Re: 天地一蟲 2014-09-18 10:00发表 [回复]
回复chaijunkun:使用RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(privateKey)); 转换的时候抛出的异常!密钥是由C++端下发的,我手上只有一个密钥串,C++端也是使用OpenSSL生成的公私钥。同样的,我用C++提供的公钥验签就没有问题!很不解!
Re: JackCousins 2014-09-19 09:42发表 [回复]
回复charlie555:用C++公钥验签?你提供的代码是加载私钥的呀,是不是私钥的格式不是PKCS#1的?
17楼 RockoZZ 2014-08-23 11:27发表 [回复]
顶一个,我想问下博主以下的另外两种获取密钥的的方法一般在哪些场景使用,刚学RSA加密不是太懂,thanks
/*通过公钥byte[](publicKey.getEncoded())将公钥还原*/
//获取公钥
public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException,
InvalidKeySpecException
{
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
//获取私钥
.....
/*使用N、e值还原公钥,使用N、d值还原私钥*/
//使用N、e值还原公钥
囧 代码过多发不出。。。
//使用N、d值还原私钥
......
Re: JackCousins 2014-08-25 09:38发表 [回复]
回复BBLD_:首先要了解RSA加解密的理论基础,至少知道公式。公式中n为明文,c为密文。
加密:
n^e = c (mod N)
解密:
c^d = n (mod N)
(N,e)是公钥,(N,d)是私钥。N是两个很大的质数乘积。也就是说常规RSA是通过公钥加密、私钥解密的(其实用私钥尝试加密也是可以的,但是主要用于签名,公钥尝试去解密的过程实际上就是验证签名)
换句话说,如果你拥有了N、e、d这三个参数就可以实现加解密。你说的第一种方法实际上是通过一种标准格式的数据(在什么位置,多大长度,保存了哪个参数都是规定好的)来让程序自动提取这些参数。而第二种方式就更为直接了,直接设置N、e、d。所以从本质上来说是没什么不同的。不过生产环境中推荐使用第一种。
16楼 Jonix 2014-08-20 08:41发表 [回复]
使用openssl生成的密钥,用C++ with openssl 库生成的密文,自己可解,用你的代码java端解不了。
但java生成的密文,c++可解。

原因不明 ...
Re: JackCousins 2014-08-21 09:25发表 [回复]
回复Jonix:由于公私钥都能加密和解密,请具体说一下应用场景,C++用哪个密钥加密的,另外Java端用什么加密的?
Re: Jonix 2014-08-21 12:00发表 [回复]
回复chaijunkun:密钥全总是用 openssl 生成的。
C++用公钥加密,java用私钥解密。
不过反过来也试过,C++用私钥加,java用公钥解,同样不行。
但C++自己加解是可以的。
Java自己加解也是可以的。
另外:网上另一篇:
http://www.cnblogs.com/fengfeng/archive/2013/08/22/3274676.html
这个文章我原样下来,也是不行的。
初步怀疑是Java的rsa算法可能也有版本之分,然后它的版本比较旧。
Re: JackCousins 2014-08-21 13:14发表 [回复]
回复Jonix:用OpenSSL生成私钥要注意密钥的编码制式,在加载私钥的时候要严格按照编码制式来(例如PKCS#8、PKCS#1)。另外在文中你搜索“cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());”,尝试使用BouncyCastleProvider和不使用两种情况下哪个可以跨语言加解密。之前开发过一个和Flash播放器之间用RSA加解密的项目,我这边用了这个Provider反而对方解不了,不用就好了。
Re: Jonix 2014-08-21 13:52发表 [回复]
回复chaijunkun:这个类不认识,请问怎么引入?

我是搞C++的,对java很不了解,而且我在linux下用的。
另外忘提了,我用的是openJDK 1.7.0.55

麻烦了,如果有类似的博文也可以,谢谢
Re: JackCousins 2014-08-21 15:33发表 [回复]
回复Jonix:如果Java项目使用maven,增加如下依赖就可以了
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
如果没有,去官网下载。具体使用方式在本文中搜索BouncyCastleProvider
Re: Jonix 2014-08-21 16:03发表 [回复]
回复chaijunkun:搞定了,非常感谢。
这个类一加上就OK了。
15楼 qq_17761359 2014-07-16 21:14发表 [回复]
请教一个问题:
openssl生成的密钥对,给我的java端一个base64的公钥,我用java代码做了RSA+DES方式进行加密(数据用DES加密,DES_KEY 用PUBLIC_KEY进行加密后传输),传输到php服务端,进行解密(会同时传输MD5(A|B|C|D)生成的签名。
因为第一次接触加密问题,请求给服务端的数据,密钥校验失败。
Re: JackCousins 2014-07-17 16:47发表 [回复]
回复qq_17761359:我跟Flash播放器进行RSA联调的时候也出现了这个问题。如果密钥的方式失败的话,尤其是跨语言联调,建议传输公私钥采用原始RSA参数的形式,任何支持RSA加解密的语言都会提供设置:n【公私钥都有的】,d【公钥包含的】和e【私钥包含的】这三个参数。
14楼 飘逝的落叶纷飞 2014-07-11 17:14发表 [回复]
有个问题想问楼主,由X509EncodedKeySpec生成公钥,其参数pubKeyText是怎样获得的呢?格式又是怎样的呢?楼主能不能给个示例。
楼主有没有试过由C# RSACryptoServiceProvider类产生公钥字符串,然后由X509EncodedKeySpec生成java类型的RSA公钥,再对数据进行加密。
Re: JackCousins 2014-07-12 22:55发表 [回复]
回复dslinmy:C#没研究过
Re: JackCousins 2014-07-12 22:54发表 [回复]
回复dslinmy:你说的这种逆过来的操作我没有研究过,如果你有兴趣可以把RSA中的各个参数提取出来(n【公私钥都有的】,d【公钥包含的】和e【私钥包含的】),转换为十六进制看一下。
Re: 飘逝的落叶纷飞 2014-07-13 08:12发表 [回复]
回复chaijunkun:正在尝试中...
13楼 Ringo胡 2014-07-10 17:51发表 [回复]
楼主你好,想请问你关于
"这时候的私钥还不能直接被使用,需要进行PKCS#8编码:
[root@chaijunkun ~]# openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
".
我在做支付宝的接口,已经有一个不能使用的私钥,有什么方法在java中直接把这个私钥转成PKCS8格式的私钥呢?
两年了,,,不知道你还有没有在留意这个文章...
Re: JackCousins 2014-07-10 20:57发表 [回复]
回复hu85730336:一直在更新自己的文章,你说的问题我已经补充了,请在正文中查找“2014年5月20日补充”
Re: Ringo胡 2014-07-11 09:03发表 [回复]
回复chaijunkun:多谢楼主,,,之前没看懂这段,,,原来RSA加密就是把PKCS1转成PKCS8,多谢!
Re: JackCousins 2014-07-11 09:26发表 [回复]
回复hu85730336:额。。。RSA不是“把PKCS1转成PKCS8”,那段描述只是说可以采用不同的私钥格式:)
12楼 keaixiaozhu7688 2014-06-30 14:55发表 [回复]
大神请问下单独做解密是不是只需要调用decrypt方法就行了,main方法里 byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
这个cipher可以直接用客户端提交上来的密文.getbytes()吗?谢谢
Re: JackCousins 2014-06-30 17:20发表 [回复]
回复keaixiaozhu7688:是的,解密直接调用decrypt方法就可以了。密文方面我建议你在客户端先做个Base64编码之后再用HTTP提交,收到内容后进行Base64解码再解密。
Re: keaixiaozhu7688 2014-06-30 17:40发表 [回复]
回复chaijunkun:加载私钥成功
密文长度:128
9c 76 55 cd 24 56 65 07 ff cf ca 48 a6 16 2e 46 13 bf c7 86 4f 0e d1 6e eb 40 2b f7 f0 f3 98 64 f0 15 8a b6 7b 9f f0 cb 8f 2c 64 21 4e fe d9 2e b4 35 fd 40 22 d7 4d 39 3b 73 a9 09 7b 62 33 4c a5 bf f7 f9 01 71 6a 18 ae 1a e0 64 f2 90 56 b2 f2 71 c9 bb 99 0e e5 df 28 c7 5e 42 9a 74 03 d8 4f 29 f8 2c db d9 a9 a2 ea 2b f3 3a 0b 15 bf af 1c 8a a0 cf d8 5e 85 4f 63 f1 4d 1c a2 4f 04 4b
明文长度:128
93 5a 64 7a 06 70 d9 21 8b 80 3d 69 10 eb 4f d5 ed a1 93 3e 28 d5 97 1b 0a d3 e3 66 6c 86 40 d3 f6 4c b6 14 36 7f 06 2b e9 47 be 97 8d 27 74 06 38 ae a9 b1 fc 73 99 cb 9b de 60 7b fb 4c 4d c7 67 22 15 8a bd 1b a9 34 6d 15 58 2b d5 60 f3 45 2b 12 77 00 67 ec 77 91 54 ce 24 56 eb 8c 8c ff fd 6c 88 97 27 e6 8a 26 23 5e 38 01 d9 3b 16 3b aa 1f 58 06 61 3c ba e6 c4 92 82 8c c0 7d 80 f7
?Zdzp?!??=i?O枕??>(??
鱼fl?@遇L?6+?G???'t8?┍?s????`{?LM?g"???4mX+?`?E+wg?w?T?$V?????l??'??&#^8?;;?Xa<烘?????}??
Re: keaixiaozhu7688 2014-06-30 17:45发表 [回复]
回复keaixiaozhu7688:服务端代码:
String name = request.getParameter("name");
BASE64Decoder base64Decoder= new BASE64Decoder();
RSAEncrypt rsaEncrypt= new RSAEncrypt();
try {
File file = new File("/Users/stevepan/pkcs8_rsa_private_key.pem");
InputStream in = new FileInputStream(file);
rsaEncrypt.loadPrivateKey(in);
System.out.println("加载私钥成功");
} catch (Exception e) {
System.err.println(e.getMessage());
System.err.println("加载私钥失败");
}
try {
//解密
byte[] cipher = base64Decoder.decodeBuffer(name);
byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
System.out.println("密文长度:"+ cipher.length);
System.out.println(RSAEncrypt.byteArrayToString(cipher));
System.out.println("明文长度:"+ plainText.length);
System.out.println(RSAEncrypt.byteArrayToString(plainText));
System.out.println(new String(plainText));
} catch (Exception e) {
System.err.println(e.getMessage());
}
Re: keaixiaozhu7688 2014-06-30 17:45发表 [回复]
回复keaixiaozhu7688:我是在iOS上用公钥文件public_key.der加密,服务器用pkcs8_rsa_private_key.pem文件解密,客户端提交密文之前做了base64,
Re: JackCousins 2014-07-02 09:40发表 [回复]
回复keaixiaozhu7688:您想表达什么?是解密失败吗?还是加密失败?
11楼 stevenmtk 2014-06-23 19:23发表 [回复]
按照楼主的步骤操作了一遍,受益匪浅。
但是用Java解密openssl用RSA生成的加密文件时,遇到了一个很奇怪的乱码问题,步骤如下:

1. 生成公私钥:
openssl genrsa -out rsa_private_key.pem 2048
openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

2. 生成源文件和加密文件:
echo "hello world" > data.txt
openssl rsautl -encrypt -in data.txt -inkey rsa_public_key.pem -pubin -out data.encrypted.txt

3. 在Java中解密该文件(data.encrypted.txt):
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey); // privateKey按楼主的方法得到
result = cipher.doFinal(encryptData);
String text = new String(result, "UTF-8);"

4. 发现问题:
生成的text在最后包含“hello world”字段,但在"hello world"之前还有许多乱码,不知道这些多余的信息是怎样产生的?楼主能否实验并解答一下呢?

非常感谢!

P.S.
1. openssl对源文件进行的签名,在Java中验证是成功的,说明Java中生成的key应该是没有问题的。
Re: JackCousins 2014-06-24 02:26发表 [回复]
回复stevenmtk:刚才做了一下实验,解密得到的字符串最后是明文,前面有很多类似于“���U�>�p2F�”的乱码,因为采用2048位加密,单次理论数据长度可达256字节。你原始明文长度很显然不够256字节,默认情况下,加密命令会在明文前加入填充字符。名词叫做“填充模式”,查阅相关资料,有如下四个参数:-pkcs、 -oaep、 -ssl、 -raw、-x931:采用的填充模式,上述四个值分别代表:PKCS#1.5(缺省值)、 PKCS#1 OAEP、 SSLv2、X931里面特定的填充模式,或者不填充。如果要签名,只有-pkcs和-raw可以使用。怀疑是因为填充引起的。
Re: stevenmtk 2014-06-24 11:41发表 [回复]
回复chaijunkun:感谢回复,您的怀疑是正确的,确实是填充模式导致的影响。原因如下:
Java代码中Cipher.getInstance("RSA");实际得到的为“Cipher.getInstance("RSA/ECB/NoPadding");”无填充模式,所以用来解包含填充的密文,前面会出现乱码。
改为Cipher.getInstance("RSA/ECB/PKCS1Padding");即可解密openssl生成的密文,不再有乱码。

为了验证这个猜想,我做了以下实验:
1. openssl -raw的方式加密的密文,在Java中用Cipher.getInstance("RSA")和Cipher.getInstance("RSA/ECB/NoPadding")都能够正确解密,但用Cipher.getInstance("RSA/ECB/PKCS1Padding")不能正确解密
2. openssl -pkcs(默认)方式加密的密文,在Java中可以用"RSA/ECB/PKCS1Padding"正确解密,而"RSA"或"RSA/ECB/NoPadding"的方式解密,明文前面都会出现乱码。
3. 剩余的-oaep、 -ssl、 -x931几种方式还没有做尝试
10楼 mlg_wing 2014-06-23 15:02发表 [回复]
你好,有没有IOS客户端的RSA加密解密demo,和服务端对应的,第一个搞RSA很迷茫
Re: JackCousins 2014-06-24 02:26发表 [回复]
回复mlg_wing:没有,我做Java的
9楼 Jymn_Chen 2014-06-08 01:45发表 [回复]
非常详细,非常使用,谢谢分享
8楼 vaintwyt 2014-04-06 15:47发表 [回复]
楼主,文章写得很详细。赞!

我想请教一下,密钥以String类型存储时,格式是怎么样的?一定要加上“\r”吗(windows下是\r\n?)~~还有就是,我用txt打开密钥文件(.pem),貌似里面没有明显的换行,不知道该在那个地方加“\r”。。
Re: vaintwyt 2014-04-06 19:16发表 [回复]
回复vaintwyt:原来不加“\r”也是可以的~~~

感谢楼主的好文!
Re: JackCousins 2014-04-07 21:47发表 [回复]
回复vaintwyt:呵呵,刚想回复你。其实加回车换行是为了好看,跟Linux里面cat出来的内容保持一致。如果不喜欢放到代码里,可以把密钥内容做成模板文件,例如Freemarker,Velocity都可以。
7楼 feiyangxiaomi 2014-03-20 17:00发表 [回复]
楼主您好,我测试使用openssl的密钥长度:
System.out.println(publicKey.getEncoded().length+"*****"); System.out.println(AES.byteArrayToString(publicKey.getEncoded()));
结果是162 bytes,我查阅了一些资料,说这是使用的DER编码。但是我现在有128 bytes密钥长度,来自于一个Ukey,我想使用这个128 bytes去加密数据,发送给Ukey。但是问题是,下面publicKey长度为128 bytes会出错,如果长度为162bytes就没问题。
KeyFactory keyFactory= KeyFactory.getInstance("RSA","BC");
X509EncodedKeySpec keySpec= new X509EncodedKeySpec(publicKey);
this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
Re: JackCousins 2014-03-20 23:11发表 [回复]
回复feiyangxiaomi:我觉得有可能你的密钥原来就不是采用的X509格式进行保存的。具体采用的格式,跟UKey的厂家进行沟通,或者参看一下Demo程序,看用的什么方式进行解密的。实际上所谓RSA算法无非起关键作用的是(n,e1)为公钥,(n,e2)为私钥的两个参数。只要把这两个参数从证书文件中解出来,就不需要用KeySpec了,直接使用java.security.interfaces.RSAPublicKey;即可进行解密
Re: feiyangxiaomi 2014-03-21 13:48发表 [回复]
回复chaijunkun:做出来了,RSAPublicKeySpec keySpec= new RSAPublicKeySpec(new BigInteger( bytepublicKey), new BigInteger("10001", 16));中bytepublicKey就是自己装载Ukey生成的128 bytes公钥。加密出来的数据和Ukey加密出来的是一样的。Ukey解密自然不是问题。
其中在Ukey中使用了#define RSA_E_0x10001 0b00000011 类型,其中私钥类型采用的noCRT。以后有问题请多多指教。。
6楼 mydearfht 2014-03-06 17:39发表 [回复]
您好,
我想请教下,如果我想在页面用公钥解密密码然后提交到后台,页面的js该如何写呢?
我试着用别人写好的加密方法进行加密,得到的结果和你的不一样.
能给一点提示吗?
Re: JackCousins 2014-03-07 13:37发表 [回复]
回复mydearfht:刚才我在网上看了一下js实现rsa算法的例子。感觉通过这种方式做加密太麻烦了。有种东西叫做HTTPS,需要隐私保护的地方完全可以使用这种东西。传输通道已经做好了加密。能给你省去不少麻烦。
5楼 小李程序猿 2013-08-20 09:53发表 [回复]
你好,我还是有个问题,我们现在使用的ssh做服务端,安卓和服务端都是靠json传输信息的,服务器这段也是靠struts的json插件完成数据转换的,那我在使用这个rsa算法的时候,该怎么拦截struts传出的json然后加密呢?
Re: JackCousins 2013-08-20 13:35发表 [回复]
回复lywwyd1314:首先我这里要做一个方向性的建议,json作为数据交换格式,可能内容会很长,而RSA这种安全算法是比较复杂的,1024位的加密也就限制了加密消息长度不能超过1024位(128字节)。我建议你不要对整个JSON进行加密解密,而是采用摘要算法将某些关键字段作为算子从而得出哈希后再进行加解密,这样既保证防止数据篡改,性能也大为提高。

其次你说的如何拦截的问题,我认为你大可以将JSON看做字符串,然后在客户端放入RequestBody中POST到服务器,服务器去整体截取RequestBody作为String来转换为JSON对象。我习惯用SpringMVC,至于Struts如何实现,建议你还是查一下相关资料。
Re: 小李程序猿 2013-08-20 23:31发表 [回复]
回复chaijunkun:我现在没有使用struts的json扩展,而是使用的最原始的printwriter。。已经实现加密了,但只能加密很短的字符串。。
还有啊,你的方法返回的是byte[]数组,那我返回给安卓设备的时候,好像不能为byte[]的,然后我又调用了byteArrayToString方法,现在已经传输给了安卓,但是问题是怎么从String转回来呢?那个算法真心不太懂哦…………
Re: JackCousins 2013-08-21 11:38发表 [回复]
回复lywwyd1314:对于byte[]字节数组的返回类型,往往都是原始数据,这些数据中如果强制对应ASCII字符,就会发现有好多不可见字符。HTTP协议最擅长的是传输文本。所以推荐你使用Base64算法对byte[]数据进行编码。这样得出的肯定是可见字符,然后传输到客户端再用Base64解密。如果你对Base64算法不熟悉可以用现成的apache-commons-codec包,org.apache.commons.codec.binary.Base64组件可以很方便地实现编解码。
Re: 小李程序猿 2013-08-20 23:27发表 [回复]
回复chaijunkun:恩,晚上的时候果然碰到你说的长度的问题了,从数据库中取出来的数据太长了,不能加密,但是我对你说的那个摘要算法还不是太了解,什么是关键字段呢,上网查的时候,也有人说得出hash之后再加密,但是这点真的不是太了解呢,因为这些加密算法的问题,原来没有写过,现在只不过是用到了才会写。。。
Re: JackCousins 2013-08-21 11:46发表 [回复]
回复lywwyd1314:其实我说的只是一个思路,不知道你做过oauth接入没。很多系统都采用签名的机制。将请求参数a=xx&b=xxx&amp;c=x都拿出来,按照参数名称英文字母表顺序排列拼接字符串再带上参数如:参数1:参数1值,参数2:参数2值,后面再加上一个固定的字符串,最后取MD5,这个就是摘要,写成公式就是:MD5(k1:v1,k2:v2,kn:vn+"const string"),因为MD5是定长的,用它再做RSA加解密就容易了。这只是一个实例,加密解密的过程在于设计,但无非也就是签名、哈希、加密这几步骤。我只能帮你到这了,不能说得太透了
Re: 小李程序猿 2013-09-04 07:22发表 [回复]
回复chaijunkun:恩 看过一些oauth2.0的,然后看了你的提示,我现在想到的解决方案是先在设备端做一个对接签名,然后等服务端和设备端牵手成功之后再把未加密的那些数据传给设备端,不知道这个方式怎么样?你觉着合适吗?
我看那个rsa加密也挺慢的了。还是不要加密太多东西吧……
Re: JackCousins 2013-09-04 13:27发表 [回复]
回复lywwyd1314:确实RSA加密的速度很慢了。我觉得民用级别,考虑使用HTTPS来传输数据就可以了,没必要自己搞一套加密的算法把内容全部加密。费力不讨好的。而且HTTPS是标准。参考文献更多。专注于业务开发,那些HTTPS的配置交给运维人员去解决就好。
Re: 小李程序猿 2013-09-04 07:24发表 [回复]
回复lywwyd1314:其实我们经理的意思 是把数据库里的一些需要展示给用户的数据全都加密。我都搞不懂这有什么好加密的…………哎……反正都是要让别人看到的,加密了也没用啊
4楼 lattimore 2013-07-23 15:03发表 [回复]
再请教个问题。
是不是可以用私钥加密公钥解密阿?
thanks
Re: JackCousins 2013-07-24 10:26发表 [回复]
回复lattimore:用私钥加密公钥解密是可以的,网上有人说私钥加密公钥解密解不开,这绝对是错误的。可以解开,也可以看到数据。但是私钥包含更多的信息,强烈不赞成将私钥公布出去的做法。实在不行可以做两对密钥。当A发消息给B时,A用B的公钥加密;当B发消息给A时,B用A的公钥加密。
Re: lattimore 2013-07-26 21:04发表 [回复]
回复chaijunkun:Thanks a lot!
3楼 lattimore 2013-07-23 15:01发表 [回复]
好文,正需要!
2楼 songbai1211 2013-01-12 00:24发表 [回复]
非常感谢楼主的分享精神啊,哎,现在大家都做加密,没一点分享精神,网上找来找去都是tmd的同样的那一两个文章,弄的都块蛋疼了,再次谢谢楼主,
Re: JackCousins 2013-01-15 09:52发表 [回复]
回复songbai1211:人人为我,我为人人。不客气
1楼 huchangyue 2012-08-07 11:20发表 [回复]
您好,大虾!我想请教您一个问题。如果生成的私钥文件是带密码的,用java怎么来解析带密码的私钥文件?求赐教!
Re: JackCousins 2012-08-08 11:15发表 [回复]
回复huchangyue:这个问题开始的时候我也研究来着,后来没弄出来,就放弃了。这部分国内的资料比较少,还是得去国外的网站上看看,用Google多搜搜吧。
Re: huchangyue 2012-08-09 09:37发表 [回复]
回复chaijunkun:您好,我还想请教你一个问题。如果生成的私钥文件不进行PKCS#8编码,java怎么解析?或者是不使用命令编码,用代码怎么来进行PKCS#8编码?
Re: JackCousins 2012-08-09 16:14发表 [回复]
回复huchangyue:针对不同加密的私钥文件java应该有提供相应的KeySpec。这些类都存在于java.security.spec包中。如果想知道哪一个适合自己,还应该多查查资料。我提供的代码也只是个入门,文档还是离不开的。多看看官方资料吧。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
src="http://blog.csdn.net/common/ad.html?t=5&containerId=ad_bot&frmId=ad_frm_1" style="border-width: 0px; overflow: hidden; width: 988px; height: 0px;" scrolling="no" id="ad_frm_1" frameborder="0">
核心技术类目
全部主题HadoopAWS移动游戏JavaAndroidiOSSwift智能硬件DockerOpenStackVPNSparkERPIE10EclipseCRMJavaScript数据库UbuntuNFCWAPjQueryBIHTML5SpringApache.NETAPIHTMLSDKIISFedoraXMLLBSUnitySplashtopUMLcomponentsWindows MobileRailsQEMUKDECassandraCloudStackFTCcoremailOPhone CouchBase云计算iOS6Rackspace Web AppSpringSideMaemoCompuware大数据aptechPerlTornadoRubyHibernateThinkPHPHBasePureSolrAngularCloud FoundryRedisScalaDjangoBootstrap
  • 个人资料

  • chaijunkun
    • 访问:436393次
    • 积分:4965
    • 等级:
    • 排名:第2560名
    • 原创:56篇
    • 转载:12篇
    • 译文:8篇
    • 评论:375条
  • 文章分类
  • Java笔记(37)
  • JSON(2)
  • MongoDB(3)
  • memcache相关技术(2)
  • Qt研究(5)
  • Android研究(1)
  • 研究成果(43)
  • 系统运维相关(4)
  • Delphi笔记(9)
  • 摘抄笔记(12)
  • Hadoop相关(2)
  • 翻译(1)
  • redis相关技术(1)
  • xml(1)
  • 开发技巧(4)
  • 团队开发(2)
  • HBase相关(1)
  • 杂谈(1)
  • 文章存档
    • 2015年05月(1)
    • 2015年04月(2)
    • 2015年03月(1)
    • 2014年10月(1)
    • 2014年07月(1)
      展开
  • 阅读排行
  • Java中获取文件大小的正确方法(36412)
  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密(28364)
  • VS2010中“工具>选项中的VC++目录编辑功能已被否决”解决方法(27703)
  • MongoDB安装为Windows服务方法与注意事项(15551)
  • 解决“没有找到 rtl100.bpl,因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。”(14418)
  • 解决Windows Update(Windows更新)出现800B0001故障的方法(14035)
  • 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法(13118)
  • Java中JSON解析器的一点见解(11612)
  • MongoDB与Jackson JSON结合实现接口敏捷开发(11366)
  • Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程(11133)
  • 评论排行
  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密(82)
  • Linux中Apache+Tomcat+JK实现负载均衡和群集的完整过程(60)
  • VS2010中“工具>选项中的VC++目录编辑功能已被否决”解决方法(20)
  • 关于Qt信号与槽机制的传递方向性研究(18)
  • ANSI编码和Unicode编码的不同(14)
  • 解决Spring定时计划任务重复执行两次(实例被构造两次)问题的方法(14)
  • Android 4.0 SDK的离线方式安装(13)
  • Java Web开发中,自定义过滤器被执行两次的原因分析及解决办法(13)
  • 基于注解的Spring MVC与JPA如何解决实体的延时加载问题(10)
  • Java应用打包后运行需要注意编码问题(10)
  • 推荐文章
  • src="http://blog.csdn.net/common/ad.html?t=12&containerId=ad_commend&frmId=ad_frm_2" style="border-width: 0px; overflow: hidden; width: 266px; height: 200px;" scrolling="no" id="ad_frm_2" frameborder="0">
  • 最新评论
  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    chaijunkun:@sinat_30047989:首先能否调通各自的加解密?例如android自己和服务器自己能否实现...

  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    chaijunkun:@landerson:Python我不熟悉,您说的我没有做过

  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    sinat_30047989:我这边用您的代码在android端把加密后的数据用Base64编码成字符串后经过网络传递到java端...

  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    landerson:老大,有整过python用私匙加密,然后在安卓里用公匙解密不?搞了老大天,解出来都是乱码。已经是有P...

  • Linux中编译、安装nginx

    applebite:还比较详细啊

  • JPA中实现两个表的非索引列(非主键列)关联

    zcy0521:这个必须要感谢一下,一直在找这问题的解决办法。太谢谢啦name是当前表字段,referencedCo...

  • maven的jetty插件提示No Transaction manager found导致启动慢的解决方法

    chaijunkun:@CrakerWei:Address already in use说明已经被占用了……Tomcat和...

  • Java中使用OpenSSL生成的RSA公私钥进行数据加解密

    chaijunkun:@AniuLincion:根据提示应该是类org.bouncycastle.asn1.ASN1Obj...

  • maven的jetty插件提示No Transaction manager found导致启动慢的解决方法

    CrakerWei:加了之后显示 Address already in use:bind,不过把Tomcat关闭之后就行...

  • maven的jetty插件提示No Transaction manager found导致启动慢的解决方法

    CrakerWei:OK了,给力!不过好像加了之后不能启动Tomcat啊,不然会显示 Address already i...

src="http://ad.csdn.net/log.ashx?t=view&adtype=ms1408&adurl=http%3A%2F%2Fad.csdn.net%2Fadsrc%2Fhp-iss-cloud-zhiding-banner-peisong-960-90-30k.swf&r_m=358" style="width: 1px; height: 1px; position: absolute; visibility: hidden;">
查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 什么是依赖注入?

    我们大家近几年都接触过一个前端框架叫做 angularjs&#xff0c;里面对它对描述非常简单&#xff0c;MVW&#xff08;Model-View-Whatever&#xff09;、模块化、自动化双向数据绑定、语义化标签、依赖注入&#xff0c;每一个标签都非常都高大上&#xff0c;就跟我们看名片一样…...

    2024/4/21 11:46:35
  2. 【实战篇】egg+vue+mongodb实践开发在线文档管理平台——水墨文档

    大厂技术 高级前端 Node进阶点击上方 程序员成长指北&#xff0c;关注公众号回复1&#xff0c;加入高级Node交流群转载自&#xff1a;围的围https://segmentfault.com/a/1190000037621367最近有小伙伴经常问实战内容&#xff0c;这篇不错&#xff0c;可以学习下&#xff01;前…...

    2024/4/21 11:46:34
  3. angularjs +boostrap后台模板实现原理

    ngbootstrap可以做出很漂亮的管理系统出来&#xff0c;https://wrapbootstrap.com/可以付费购买&#xff0c;下文会提供一个免费的&#xff0c;要讲解如何从0到1把ng前端结构搭出来是很漫长的教程&#xff0c;本文仅仅介绍一下这个免费后台模版的结构&#xff0c;然后重点讲解如…...

    2024/4/21 11:46:34
  4. 把http修改成https

    随着国内搜索引擎巨头百度启用全站https加密服务&#xff0c;国内进入https加密时代。越来越多的站点希望通过部署https证书来解决“第三方”对用户隐私的嗅探和劫持。谷歌方面作为推动网站https加密先驱&#xff0c;早在2010年5月便开始提供https加密搜索服务。谷歌在算法更新…...

    2024/4/28 4:22:45
  5. 快递鸟电子面单打印接口demo-可返回电子面单模板

    接口支持的消息接收方式&#xff1a;HTTPPOST请求方法的编码格式(utf-8)&#xff1a;"application/x-www-form-urlencoded;charsetutf-8"请求、返回数据类型&#xff1a;只支持JSON格式接口提供&#xff1a;快递鸟电子面单可直接返回模板&#xff08;JAVA对接源码&am…...

    2024/4/29 0:59:38
  6. 双眼皮术后三月

    ...

    2024/4/28 3:06:31
  7. 双眼皮术后可以开车么

    ...

    2024/4/29 8:32:15
  8. 双眼皮术后不照镜子

    ...

    2024/5/2 19:06:06
  9. 华为OD软件工程师面试总结

    一、自身基本情况二战考研狗,且没有工作经历,只能走社招;然后我在boss直聘上面挂着我的简历,然后幸运的遇到一个校友HR,最后面试了西安研究所云核心网产品线软件工程师。二、面试1.机试题题目分值:每套题目2道中级题,每题200分,总分400分,120分合格考试时长:90分钟可…...

    2024/4/28 13:37:56
  10. 双眼皮术后冰敷用什么意思

    ...

    2024/4/28 12:32:25
  11. ng bootstrap css,Angular2中Bootstrap界面库ng-bootstrap详解

    准备 Angular 2 环境ng-bootstrap 是基于 Angular 2 的&#xff0c; 因此需要先准备 Angular 2 的环境。使用 ng-bootstrap下载 ng-bootstrapng-bootstrap 使用 bootstrap 4.0 alpha2 &#xff0c; 因此需要先下载 bootstrap &#xff0c; 推荐使用 npm 包的形式&#xff1a;np…...

    2024/4/28 19:03:56
  12. ng-dropdown-multiselect使用

    下拉多选框 1.ng-dropdown-multiselect使用 下载并引用ng-dropdown-multiselect.js文件&#xff0c; Html文件&#xff1a; 《div> ng-dropdown-multiselect"" style“margin-top:6px” options“modalityTypes” selected-model“modalityTypesModel” extra-set…...

    2024/4/28 13:02:40
  13. 双眼皮术后 防止过敏

    ...

    2024/4/28 0:58:23
  14. 双眼皮手术做一只眼吗

    ...

    2024/4/28 4:04:15
  15. 像踢球一样玩转Redux和React

    引言 React的核心是使用组件定义界面的表现&#xff0c;是一个View层的前端库&#xff0c;简单来说它就是一堆前端组件&#xff0c;view&#xff0c;view&#xff0c;view&#xff0c;重要的事情说三遍。 可是有了组件以后&#xff0c;要怎么组织前端界面的表现呢&#xff1f;怎…...

    2024/4/29 2:07:34
  16. Redux 进阶

    系列文章: Redux 入门Redux 进阶(本文)番外篇: Vuex — The core of Vue application在之前的文章中&#xff0c;我们已经了解了 Redux 到底是什么&#xff0c;用来处理什么样的问题&#xff0c;并创建了一个简单的 TodoMVC Demo。但是&#xff0c;我们同样遗留了一些问题没有处…...

    2024/4/28 11:54:33
  17. [译] 2019 React Redux 完全指南

    原文地址&#xff1a;A Complete React Redux Tutorial for 2019原文作者&#xff1a;Dave Ceddia译文出自&#xff1a;掘金翻译计划本文永久链接&#xff1a;github.com/xitu/gold-m…译者&#xff1a;xilihuasi校对者&#xff1a;xionglong58、Fengziyin12342019 React Redux…...

    2024/4/29 1:14:14
  18. Redux学习 React+Redux实战(connect方法各个参数解读)

    本文复制了官网许多概念&#xff0c;稍加整合知识点使之变得更合理完整&#xff0c;以个人的认为比较好的学习路线循序渐进各个知识点&#xff0c;额外也会补充些许知识点。大家若有不解&#xff0c;还请多参阅官网。 本文示例背景(最常见的 Web 类示例)&#xff1a; TodoList…...

    2024/4/28 15:59:27
  19. 双眼皮手术左右不对称怎么修复

    ...

    2024/4/28 19:20:04
  20. React Redux 介绍

    Redux 介绍 文章目录Redux 介绍一.简介二.Redux 三大原则1.单一数据源2.state是只读的3.使用纯函数来执行修改3.1 纯函数三.Redux的组成1.Action1.1 actionType1.2 action Create2.Reducer2.1 combineReducers()3.Store3.1 createStore()四.React中Redux的使用1.react-redux2.P…...

    2024/4/28 4:33:56

最新文章

  1. 推荐书单|提升境界、思维能力

    1、《别做正常的傻瓜》 豆瓣评分&#xff1a;8.1 通过揭示人们在日常生活中常见的非理性行为&#xff0c;引导读者认识并克服这些行为&#xff0c;从而做出更明智的决策。 2、《活法》 豆瓣评分&#xff1a;8.1 稻盛和夫分享其人生哲学和经营哲学的著作&#xff0c;强调了正确…...

    2024/5/5 18:28:01
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 腾讯云云原生数据库TDSQL-C mysql 以及项目怎么接入

    要接入腾讯云的云原生数据库TDSQL-C的MySQL版本&#xff0c;并将它用于你的项目中&#xff0c;你需要按照以下步骤进行&#xff1a; 创建TDSQL-C的MySQL数据库实例&#xff1a; 登录腾讯云控制台。在产品搜索框中搜索TDSQL-C&#xff0c;然后选择它。在TDSQL-C的产品页面上&…...

    2024/5/4 6:23:44
  4. Ubuntu磁盘扩容

    使用 df -h命令查看系统磁盘控件的使用情况&#xff1a; [samspobosrv:~]$ df -h Filesystem Size Used Avail Use% Mounted on udev 7.8G 0 7.8G 0% /dev tmpfs 1.6G 1.7M 1.…...

    2024/5/5 4:50:46
  5. 图像处理相关知识 —— 椒盐噪声

    椒盐噪声是一种常见的图像噪声类型&#xff0c;它会在图像中随机地添加黑色&#xff08;椒&#xff09;和白色&#xff08;盐&#xff09;的像素点&#xff0c;使图像的质量降低。这种噪声模拟了在图像传感器中可能遇到的问题&#xff0c;例如损坏的像素或传输过程中的干扰。 椒…...

    2024/5/5 8:37:08
  6. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  7. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  8. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  9. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/4 23:55:17
  10. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  11. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  12. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  13. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  14. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  15. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/4 18:20:48
  16. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  17. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  18. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  19. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  20. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  21. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  22. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  23. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  24. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/4 23:55:01
  25. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57