看板 java 關於我們 聯絡資訊
※系統環境: openssl 1.0.2g Java8 ※狀況概述: 我設計一個網頁來作認証使用,由網頁端提供私鑰與隨機字串, 讓使用者用私鑰來加密字串後,再傳回網頁端並使用公鑰來解密進行認證。 目前我在網頁端(Java)進行加密/解密測試都可以正常運作,但在模擬客戶端測試時, 由客戶端使用openssl用私鑰加密字串傳回網頁端時,發現網頁端解密都會失敗。 ※程式碼: 網頁端產生私鑰: KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(1024); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()); //私鑰 Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()); //公鑰 網頁端(Java): String PRIVATE_KEY = "MII........vCF4="; //私鑰 String PUBLIC_KEY = "MII.......wIDAQAB";//公鑰 String STRING = "u8xeve.....x82NA=="; //加密過後字串 String str = "XXXXXX"; //隨機字串 byte[] result; //[測試] 私鑰加密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIVATE_KEY)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT); cipher.init(Cipher.ENCRYPT_MODE, privateKey, oaepParameterSpec); result = cipher.doFinal(Base64.getDecoder().decode(str)); System.out.println("Result : " + Base64.getEncoder().encodeToString(result)); //公鑰解密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(PUBLIC_KEY)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT); cipher.init(Cipher.DECRYPT_MODE, publicKey, oaepParameterSpec); result = cipher.doFinal(STRING.getBytes()); System.out.println("Result : " + Base64.getEncoder().encodeToString(result)); 客戶端(openssl): # encr.txt - 隨機字串 # private.pem - 私鑰(需要在檔案開頭與結尾各加上 # '-----BEGIN PRIVATE KEY-----'與'-----END PRIVATE KEY-----') openssl pkeyutl -in encr.txt -encrypt -inkey private.pem \ -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 \ -pkeyopt rsa_mgf1_md:sha256 |openssl base64 ※錯誤訊息: cipher.doFinal(Base64.getDecoder().decode(str)) <-- unable to decrypt block -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.115.97.79 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/java/M.1577773839.A.3FE.html ※ 編輯: kuangs (59.115.97.79 臺灣), 12/31/2019 14:48:17 ※ 編輯: kuangs (59.115.97.79 臺灣), 12/31/2019 14:50:02
ssccg: 用私鑰加密、用「公鑰」解密,那加密的意義在哪? 12/31 16:49
ssccg: 如果是認證應該用簽章演算法 12/31 16:58
reon: 不要亂用啊..私鑰只能用來解密和簽章~公鑰是加密 01/19 01:34
gn00273680: 樓上正確 01/25 15:40