Java 程式設計(一)  第 六章 方法與套件引用  上一頁   

 

6-6 專題研討

內容:

  • 6-6-1 範例研討:製作 DES 加密/解密工具

  • 6-6-2 範例研討:產生 RSA 鑰匙配對程式

6-6-1 範例研討:製作 DES 加密/解密工具

(A) 程式功能:Ex6_7.java

請製作一只 DES (Data Encryption Standard) 密碼系統加密/解密功能的雛形工具,系統允許使用者輸入明文與產生鑰匙元素後,即顯示加密後密文,以及解密後明文,操作介面如下:

D:\Java1_book\chap6>javac -encoding utf8 Ex6_7.java

 

D:\Java1_book\chap6>java Ex6_7

請輸入明文 =>大家恭喜、新年快樂

請輸入密碼元素(8 個字元) =>12345678

密碼元素:12345678

明文:大家恭喜、新年快樂

加密後密文:h\$:?!廄礓v?JX5Q?

解密後明文:大家恭喜、新年快樂

 (B) 製作技巧提示

要將 DES 密碼系統演算法轉換為程式,是一件不容易的工作,我們可利用 Javax.crypto 套件下的類別程式來完成。

(C) 程式範例:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

//Ex6_7 DES 加密/解密程式

 

import java.security.SecureRandom; 

import java.util.Scanner;

import javax.crypto.Cipher; 

import javax.crypto.SecretKey; 

import javax.crypto.SecretKeyFactory; 

import javax.crypto.spec.DESKeySpec; 

 

public class Ex6_7 { 

 

    public static void main(String[] args) {

              Scanner keyin = new Scanner(System.in);

           System.out.print("請輸入明文 =>");

        String plain = keyin.nextLine();

              System.out.print("請輸入密碼元素(8 個字元) =>");

        String key = keyin.nextLine();

        System.out.println("密碼元素:" + key); 

        System.out.println("明文:" + plain); 

        byte[] cipher = encrypt(plain, key); 

        System.out.println("加密後密文:" + new String(cipher)); 

        String cipher_n = decrypt(cipher, key); 

        System.out.println("解密後明文:" + cipher_n); 

    } 

 

    // DES 加密程式

    public static byte[] encrypt(String plain, String key) { 

        try { 

            SecureRandom random = new SecureRandom(); 

            DESKeySpec desKey = new DESKeySpec(key.getBytes());  

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 

            SecretKey securekey = keyFactory.generateSecret(desKey); 

            Cipher cipher = Cipher.getInstance("DES"); 

            cipher.init(Cipher.ENCRYPT_MODE, securekey, random); 

            byte[] result = cipher.doFinal(plain.getBytes()); 

            return result; 

        } catch (Throwable e) { 

            e.printStackTrace(); 

        } 

        return null; 

    } 

 

    //解密程式

    public static String decrypt(byte[] content, String key) { 

        try { 

            SecureRandom random = new SecureRandom(); 

            DESKeySpec desKey = new DESKeySpec(key.getBytes()); 

            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 

            SecretKey securekey = keyFactory.generateSecret(desKey); 

            Cipher cipher = Cipher.getInstance("DES"); 

            cipher.init(Cipher.DECRYPT_MODE, securekey, random); 

            byte[] result = cipher.doFinal(content); 

            return new String(result); 

        } catch (Throwable e) { 

            e.printStackTrace(); 

        } 

        return null; 

    } 

6-6-2範例研討:產生 RSA 鑰匙配對程式

(A)程式功能:Ex6_8.java

請製作一套 1024 位元的 RSA 鑰匙配對產生工具,每次執行時會產生不同的鑰匙配對(公開鑰匙與私有鑰匙),期望操作介面如下:

期望操作介面如下:

D:\Java1_book\chap6\RSA>javac -encoding utf8 Ex6_8.java

 

D:\Java1_book\chap6\RSA>java Ex6_8

產生RSA 鑰匙配對中

將鑰匙配對寫入檔案,並顯示於螢幕

Public Key: 30819f300d06092a864886f70d010101050003818d....

.....

由檔案讀出 RSA 鑰匙配對,並顯示於螢幕

Public Key: 30819f300d06092a864886f70d0101010500…….

……

D:\Java1_book\chap6\RSA>dir/b *.key

private.key     // 私有鑰匙檔案

public.key      // 公開鑰匙檔案

(B)製作技巧提示

我們利用 Java.scurity 套件內,產生 RSA 鑰匙配對方法。

(C)程式範例:

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

// Ex6_8.java

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.SecureRandom;

import java.security.KeyFactory;

import java.security.NoSuchAlgorithmException;

import java.security.PrivateKey;

import java.security.PublicKey;

import java.security.spec.InvalidKeySpecException;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

 

public class Ex6_8 {

                public static void main(String[] args) {

                myKeyPair adam = new myKeyPair();

                try {

                        String path = ".";

                        // Generate the key pair (public key and private key)

                        KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");

                        SecureRandom random = new SecureRandom();

                        // 給與亂數因子,指定鑰匙長度,再產生鑰匙

                        System.out.println("產生RSA 鑰匙配對中");

                        random.setSeed("seedVaule".getBytes());

                        keygen.initialize(1024, random);           // Generate 1024-bit keys

                        KeyPair generatedKeyPair = keygen.generateKeyPair();

                        // 儲存鑰匙配對

                        System.out.println("將鑰匙配對寫入檔案,並顯示於螢幕");

                        adam.dumpKeyPair(generatedKeyPair);        // Print the generated keys

                        adam.SaveKeyPair(path, generatedKeyPair);  // Store the keys into two files

                        // 讀取鑰匙配對

                        System.out.println("\n由檔案讀出 RSA 鑰匙配對,並顯示於螢幕");

                        KeyPair loadedKeyPair =

                                        adam.LoadKeyPair(path, "RSA");     // Load the keys from files

                        adam.dumpKeyPair(loadedKeyPair);           // Print the loaded keys

                } catch (Exception e) {

                        e.printStackTrace();

                        return;

                }

        }

}

 

class myKeyPair {

        // 列印鑰匙配對方法

        public void dumpKeyPair(KeyPair keyPair) {

                PublicKey pub = keyPair.getPublic();

                System.out.println("Public Key: " + getHexString(pub.getEncoded()));

               

                PrivateKey priv = keyPair.getPrivate();

                System.out.println("Private Key: " + getHexString(priv.getEncoded()));

                }

       

        public String getHexString(byte[] b) {

                StringBuilder result = new StringBuilder();

                for (int i = 0; i < b.length; i++)

                        result.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));

                return result.toString();

                }

               

        // 將鑰匙配對寫入檔案方法

        public void SaveKeyPair(String path, KeyPair keyPair) throws IOException {

                PrivateKey privateKey = keyPair.getPrivate();

                PublicKey publicKey = keyPair.getPublic();

               

                // 儲存公開鑰匙

                X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(

                    publicKey.getEncoded());

                FileOutputStream fos = new FileOutputStream(path + "/public.key");

                fos.write(x509EncodedKeySpec.getEncoded());

                fos.close();

                // 儲存私有鑰匙

                PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(

                     privateKey.getEncoded());

                fos = new FileOutputStream(path + "/private.key");

                fos.write(pkcs8EncodedKeySpec.getEncoded());

                fos.close();

        }

       

        // 由檔案中讀取鑰匙配對方法

        public KeyPair LoadKeyPair(String path, String algorithm)

                throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

                // 讀取公開鑰匙

                File filePublicKey = new File(path + "/public.key");

                FileInputStream fis = new FileInputStream(filePublicKey);

                byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];

                fis.read(encodedPublicKey);

                fis.close();

               

                // 讀取私有鑰匙方法

                File filePrivateKey = new File(path + "/private.key");

                fis = new FileInputStream(filePrivateKey);

                byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];

                fis.read(encodedPrivateKey);

                fis.close();

       

                // Generate KeyPair.

                KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

                X509EncodedKeySpec publicKeySpec = new

X509EncodedKeySpec(encodedPublicKey);

                PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

               

                PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(

                                encodedPrivateKey);

                        PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

                               

                        return new KeyPair(publicKey, privateKey);

       

        }

}

翻轉工作室:粘添壽

 

Java 程式設計(一) 含程式邏輯

 

 

翻轉電子書系列: