<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    #

    查看密鑰

    密匙生成后,可以隨時用以下命令查看。

    查看所有密鑰:
    snapshot9.png

    查看所有公鑰:
    snapshot10.png

    查看所有私鑰:
    snapshot11.png

    列出所有簽名:
    snapshot12.png


    導出公鑰

    在非對稱加密體系中,私鑰是由用戶保管,而公鑰是對外公開的。用戶在生成密鑰對后,需要把其中的公鑰導出到一個文件中,然后將其分發給其它用戶。

    導出公鑰的方法很簡單,通過gpg命令的“-export”參數就可完成。為了使導出文件是ASCⅡ編碼的,還需要加上參數“-a”。比如,導出Terry Yu ASCⅡ編碼的公鑰文件,可以使用以下命令:
    snapshot13.png


    分發公鑰

    這個包含公鑰信息的文件需要對外分發,可以通過各種方式將terry.acs文件分發給所有與用戶有信息通信需求的人。

    最簡單的分發方式是,將該文件放到互聯網上供人下載。這種方式需要注意的問題是,所發布公鑰文件的網站一定要是一個可以信賴的站點。實際應用中,類似的做法很普遍。

    比如,Red Hat的公鑰就是在它的官方網站上發布的,任何人都可以下載獲得,并用來驗證Red Hat所發布軟件的簽名的正確性。

    posted @ 2005-09-22 14:08 ivaneeo 閱讀(279) | 評論 (0)編輯 收藏

    命令開始運行后,首先,會看到版本和路徑信息如下
    snapshot3.png

    隨后需要回答一系列問題,以幫助產生一對密鑰。首先遇到的問題是要求選擇密鑰使用的算法:
    snapshot4.png

    其中,DSA是數字簽名算法,RSA和ElGamal是兩種不同原理的非對稱密鑰算法。通常可以選擇“1”,這樣生成的密鑰可以同時用作簽名和加密兩種用途。

    接著,會要求選擇密鑰的長度:
    snapshot5.png

    這里的密鑰長度有768、1024和2048位三種。顯然,密鑰越長越安全,但太長又會影響使用的速度。所以,可以根據不同的需要選擇適合的長度。


    另外,還需要設定密鑰過期的時間:
    snapshot6.png

    原則上,密鑰使用的頻率越高,密鑰有效的時間越長,被攻擊的可能性就越大。所以,要根據應用的實際情況綜合考慮,確定一個適當的時間長度。需要注意的是,密鑰要定期更換,建議絕對不要永遠使用同一對密鑰。

    最后,需要輸入一些個人信息,包括真實姓名、電子郵件地址等,用來識別密鑰,最好是如實填寫。比如:
    snapshot7.png

    然后,必須輸入一個密碼。密碼用來保護密鑰,沒有這個密碼,任何人都不能看到密鑰本身的內容。密碼是在密鑰文件泄露后惟一的保密措施,它的最大敵人是暴力破解和字典攻擊。所以,一定要選擇一個強壯的密碼,來有效地對抗這些攻擊。

    密碼確定以后,系統開始運算:
    snapshot8.png
    這時需要隨便地敲擊鍵盤或是移動鼠標,以產生一些隨機數,協助密鑰的順利生成。注意,如果沒有以上動作,很可能最終不能產生密鑰。

    以上信息表示已經成功地為“ivan wan”生成并簽名了一對密鑰,密鑰過期時間為“2005-09-22”。在生成密鑰的同時,默認用戶目錄的.gnupg目錄中也存放了與該用戶相關的 GPG配置及密鑰存儲文件。這些文件控制了用戶的GPG環境,用戶不能直接修改這些文件,所有改動都將通過“gpg”命令實現。
    posted @ 2005-09-22 14:02 ivaneeo 閱讀(258) | 評論 (0)編輯 收藏

    建立GPG環境

    GPG軟件作為用于加密和數字簽名的開放源碼工具,許多Linux發行版本都自帶了該軟件。在默認安裝的情況下,gpg會作為一個基本命令事先安裝好。

    如果選用的Linux發行版默認沒有安裝GPG,可以通過tar包或RPM包進行安裝,可從http://www.gnupg.org/download/下載安裝包。安裝過程比較簡單,這里省略了。

    判斷是否安裝有GPG的方法也很簡單。直接在命令行下輸入“gpg -h”命令,如果系統已經安裝有GPG,就會顯示關于GPG用法的信息。

    確定Linux系統中已經安裝了GPG后,就可以開始下面加密和簽名的工作了。建立GPG環境

    GPG軟件作為用于加密和數字簽名的開放源碼工具,許多Linux發行版本都自帶了該軟件。在默認安裝的情況下,gpg會作為一個基本命令事先安裝好。

    如果選用的Linux發行版默認沒有安裝GPG,可以通過tar包或RPM包進行安裝,可從http://www.gnupg.org/download/下載安裝包。安裝過程比較簡單,這里省略了。

    判斷是否安裝有GPG的方法也很簡單。直接在命令行下輸入“gpg -h”命令,如果系統已經安裝有GPG,就會顯示關于GPG用法的信息。

    確定Linux系統中已經安裝了GPG后,就可以開始下面加密和簽名的工作了。

    生成密鑰

    用戶應用GPG,首先要有一對自己的密鑰。所以,第一步就是產生一對密鑰。gpg命令通過大量參數提供所需要的幾乎所有操作。其中,參數“-gen-key”就是用來產生一對密鑰的。在安裝了GPG的Linux系統上可以運行以下命令:
    snapshot1.png

    如果想對產生密鑰的操作進行一些個性化設置,還可以加上其它參數。比如,要指定生成密鑰存放的位置,可以運行以下命令:
    snapshot2.png
    posted @ 2005-09-22 13:49 ivaneeo 閱讀(338) | 評論 (0)編輯 收藏

    范例(Examples)
    Java 2擁有一組全新群集(collections)--并非僅僅加入一些新classes,而是完全改變了群集的風格.所以在Java 1.1Java 2中,封裝群集的方式也完全不同.我首先討論Java 2的方式,因為我認為功能更強大的Java 2 collections會取代Java 1.1 collections的地位.

    范例(Examples): Java 2

    假設有個人要去上課.我們用一個簡單的Course來表示[課程]:
    class Course...
       public Course(String name, boolean isAdvanced) {...};
       public boolean isAdvanced() {...};

    我不關心課程其他細節.我感興趣的是表示[人]的Person:
    class Person...
       public Set getCourse() {
          return _courses;
       }
       public void setCourse(Set arg) {
          _courses = arg;
       }
       private Set _courses;

    有了這個接口,我們就可以這樣為某人添加課程:
       Person kent = new Person();
       Set s = new HashSet();
       s.add(new Course("Smalltalk Programming", false));
       s.add(new Course("Appreciating Single Malts", true));
       kent.setCourses(s);
       Assert.equals(2, Kent.getCourses().size());

       Course refact = new Course("Refactoring", true);
       kent.getCourses().add(refact);
       kent.getCourses().add(new Course("Brutal Sarcasm", false));
       Assert.equals(4, kent.getCourses().size());

       kent.getCourses().remove(refact);
       Assert.equals(3, kent.getCourses().size());
    如果想了解高級課程,可以這么做:
       Iterator iter = person.getCourses().iterator();
       int count = 0;
       while(iter.hasNext()) {
          Course each = (Course)iter.next();
          if(each.isAdvanced()) count++;
       }
    我要做的第一件事就是為Person中的群集(collections)建立合適的修改函數(modifiers, 亦即add/remove函數),如下所示,然后編譯:
    class Person...
       public void addCourse(Course arg) {
          _courses.add(arg);
       }
       public void removeCourse(Course arg) {
          _courses.remove(arg);
       }

    如果我想下面這樣初始化_courses值域,我的人生會輕松得多:
       private Set _courses = new HashSet();

    接下來我需要觀察設值函數(setter)的調用者.如果有許多地點大量運用了設值函數,我就需要修改設值函數,令它調用添加/移除(add/remove)函數.這個過程的復雜度取決于設值函數的被使用方式.設值函數的用法有兩種,最簡單的情況就是:它被用來[對集群進行初始化動作].換句話說,設值函數被調用之前,_courses是個空群集.這種情況下我需要修改設值函數,令它調用添加函數(add)就行了:
    class Person...
       public void setCourses(Set arg) {
          Assert.isTrue(_courses.isEmpty());
          Iterator iter = arg.iterator();
          while(iter.hasNext()) {
             addCourse((Course)iter.next());
          }
       }
    修改完畢后,最后以Rename Method(273)更明確地展示這個函數的意圖.
       public void initializeCourses(Set arg) {
          Assert.isTrue(_courses.isEmpty());
          Iterator iter = arg.iterator();
          while(iter.hasNext()) {
             addCourse((Course)iter.next());
          }
       }

    更普通的情況下,我必須首先以移除函數(remove)將群集中的所有元素全部移除,然后再調用添加函數(add)將元素一一添加進去.不過我發現這種情況很少出現(唔,愈是普通的情況,愈少出現).

    如果我知道初始化時,除了添加元素,不會再有其他行為,那么我可以不使用循環,直接調用addAll()函數:
       public void initializeCourses(Set arg) {
          Assert.isTrue(_courses.isEmpty());
          
    _courses.addAll(arg);
       }

    我不能僅僅對這個set賦值,就算原本這個set是空的也不行.因為萬一用戶在[把set傳遞給Person對象]之后又去修改它,會破壞封裝.我必須像上面那樣創建set的一個拷貝.

    如果用戶僅僅只是創建一個set,然后使用設值函數(setter.譯注:目前已改名為initializeCourses()),我可以讓它們直接使用添加/移除(add/remove)函數,并將設值函數完全移除.于是,以下代碼:
       Person kent = new Person();
       Set s = new HashSet();
       s.add(new Course("Smalltalk Programming", false));
       s.add(new Course("Appreciating Single Malts", true));
       kent.initializeCourses(s);

    就變成了:
       Person kent = new Person();
       kent.addCourse(new Course("Smalltalk Programming", false));
       kent.addCourse(new Course("Appreciating Single Malts", true));



    接下來我開始觀察取值函數(getter)的使用情況.首先處理[有人以取值函數修改底部群集(underlying collection)]的情況,例如:
       kent.getCourses().add(new Course("Brutal Sarcasm", false));
    這種情況下我必須加以改變,使它調用新的修改函數(modifier):
       kent.addCourse(new Course("Brutal Sarcasm", false));
    修改完所有此類情況之后,我可以讓取值函數(getter)返回一個只讀映件(read-only view),用以確保沒有任何一個用戶能夠通過取值函數(getter)修改群集:
       public Set getCourses() {
          return Collections.unmodifiableSet(_courses);
       }
    這樣我就完成了對群集的封裝.此后,不通過Person提供的add/remove函數,誰也不能修改群集內的元素.

    將行為移到這個class中

    我擁有了合理的接口.現在開始觀察取值函數(getter)的用戶,從中找出應該屬于Person的代碼.下面這樣的代碼就應該搬移到Person去:
       Iterator iter = person.getCourses().iterator();
       int counter = 0;
       while(iter.hasNext()){
          Course each = (Course)iter.next();
          if(each.isAdvanced()) cout++;
       }

    因為以上只使用了屬于Person的數據.首先我使用Extract Method(110)將這段代碼提煉為一個獨立函數:
       int numberOfAdvancedCourses(Person person) {
          Iterator iter = person.getCourses().iterator();
          int count = 0;
          while(iter.hasNext()) {
             Course each = (Course)iter.next();
             if(each.isAdvanced()) count++;
          }
          return count;
       }
    然后使用Move Method(142)將這個函數搬移到Person中:
    class Person...
       int numberOfAdvancedCourses(Person person) {
          Iterator iter = person.getCourses().iterator();
          int count = 0;
          while(iter.hasNext()) {
             Course each = (Course)iter.next();
             if(each.isAdvanced()) count++;
          }
          return count;
       }

    舉個常見例子,下列代碼:
       kent.getCourses().size();
    可以修改更具可讀性的樣子,像這樣:

    kent.numberOfCourses();

    class Person...
    public int numberOfCourses() {
       return _courses.size();
    }

    數年以前,我曾經擔心將這樣的行為搬移到Person中會導致Person變得臃腫.但是在實際工作經驗中,我發現這通常并不成為問題.

    posted @ 2005-09-19 13:51 ivaneeo 閱讀(539) | 評論 (0)編輯 收藏

    • 作法(Mechanics)
      • 加入[為群集添加(add),移除(remove)元素]的函數.
      • 將[用以保存群集]的值域初始化為一個空群集.
      • 編譯.
      • 找出[群集設值函數]的所有調用者.你可以修改那個設值函數,讓它使用上述新建立的[添加/移除元素]函數;也可以直接修改調用端,改讓它們調用上述新建立的[添加/移除元素]函數.
          • ==>兩種情況下需要用到[群集設值函數];(1)群集為空時;(2)準備將原有群集替換為另一個群集時.
          • ==>你或許會想運用Rename Method(273)為[群集設值函數]改名,從setXxx()改為initializeXxx()或replaceXxx().
      • 編譯,測試.
      • 找出所有[通過取值函數(getter)獲得群集并修改其內容]的函數.逐一修改這些函數,讓它們改用[添加/移除](add/remove)函數.每次修改后,編譯并測試.
      • 修改完上述所有[通過取值函數(getter)獲得群集并修改群集內容]的函數后,修改取值函數自身,使它返回該群集的一個只讀映件(read-only view).
          • ==>在Java 2中,你可以使用Collection.unmodifiableXxx()得到該集群的只讀映件.
          • ==>在Java 1.1中,你應該返回群集的一份拷貝.
      • 編譯,測試.
      • 找出取值函數(getter)的所有用戶,從中找出應該存在于[群集之宿主對象(host object)]內的代碼.運用Extract Method(110)和Move Method(142)將這些代碼移到宿主對象去.
    • 如果你使用Java 2,那么本項重構到此為止.如果你使用Java 1.1,那么用戶也許會喜歡使用枚舉(enumeration).為了提供這個枚舉,你應該這樣做.
      • 修改現有取值函數(getter)的名字,然后添加一個新取值函數,使其返回一個枚舉.找出舊取值函數的所有被使用點,將它們都改為使用新取值函數.
          • ==>如果這一步跨度太大,你可以先使用Rename Method(273)修改原取值函數的名稱;再建立一個新取值函數用以返回枚舉;最后再修改所有調用者,使其調用新取值函數.
      • 編譯,測試.
    posted @ 2005-09-15 17:51 ivaneeo 閱讀(545) | 評論 (0)編輯 收藏

    動機(Motivation)
    class常常會使用群集(collection,可能是array,list,set或vector)來保存一組實體.這樣的class通常也會提供針對該群集[取值/設值函數](getter/setter).

    但是,集群的處理方式應該和其他種類的數據略有不同.取值函數(getter)不該返回群集自身,因為這將讓用戶得以修改群集內容而群集擁有者卻一無所悉.這也會對用戶暴露過多[對象內部數據結構]的信息.如果一個取值函數(getter)確實需要返回多個值,它應該避免用戶直接操作對象內所保存的群集,并隱藏對象內[與用戶無關]的數據結構.至于如何做到這一點,視你使用的Java版本不同而有所不同.

    另外,不應該為這整個群集提供一個設值函數(setter),但應該提供用以為群集添加/移除(add/remove)元素的函數.這樣,群集擁有者(對象)就可以控制群集元素的添加和移除.

    如果你做到以上數點,群集(collection)就被很好地封裝起來了,這便可以降低群集擁有者(class)和用戶之間的耦合度.
    posted @ 2005-09-15 15:35 ivaneeo 閱讀(364) | 評論 (0)編輯 收藏

    有個函數(method)返回一個群集(collection).

    讓這個函數返回該群集的一個只讀映件(read-only view),并在這個class中提供[添加/移除](add/remove)群集元素的函數.

    Encapsulate Collection.jpg
    posted @ 2005-09-15 15:08 ivaneeo 閱讀(401) | 評論 (0)編輯 收藏

    • 作法(Mechanics)
      • 為public值域提供取值/設值函數(getter/setter).
      • 找到這個class以外使用該值域的所有地點.如果客戶只是使用該值域,就把引用動作(reference)替換為對取值函數(getter)的調用];如果客戶修改了該值值域,就將此一引用點替換為[對設值函數(setter)的調用].
          • ==>如果這個值域是個對象,而客戶只不過是調用該對象的某個函數,那么不論該函數是否為修改函數(modifier,會改變對象狀態),都只能算是使用該值域.只有當客戶為該值域賦值時,才能將其替換為設值函數(setter).
      • 每次修改之后,編譯并測試.
      • 將值域的所有用戶修改完畢后,把值域聲明為private.
      • 編譯,測試.
    posted @ 2005-09-15 14:30 ivaneeo 閱讀(346) | 評論 (0)編輯 收藏

    動機(Motivation)
    面向對象的首要原則之一就是封裝(encapsulation),或者稱為[數據隱藏](data hidding).

    public數據被看做是一種不好的作法,因為這樣會降低程序的模塊化程度(modularity).如果數據和使用該數據的行為被集中在一起,一旦情況發生變化,代碼的修改就會比較簡單,因為需要修改的代碼都集中于同一塊地方,而不是星羅棋布地散落在整個程序中.

    Encapsulate Field(206)是封裝過程的第一步.通過這項重構手法,你可以將數據隱藏起來,并提供相應的訪問函數(accessors).但它畢竟只是第一步.如果一個class除了訪問函數(accessors)外不能提供其他行為,它終究只是一個dumb class(啞類).這樣的class并不能獲得對象技術的優勢,而你知道,浪費如何一個對象都是很不好的.實施Encapsulate Field(206)之后,我會嘗試尋找那些使用[新建訪問函數]的函數,看看是否可以通過簡單的Move Method(142)輕快地將它們移到新對象去.
    posted @ 2005-09-15 14:21 ivaneeo 閱讀(443) | 評論 (0)編輯 收藏

    你的class中存在一個public值域.

    將它聲明為private,并提供相應的訪問函數(accessors).

    public String _name

                                           126.gif
    private String _name;
    public String getName() {return _name;}
    public void setName(String arg) {_name = arg;}
    posted @ 2005-09-15 14:07 ivaneeo 閱讀(334) | 評論 (0)編輯 收藏

    僅列出標題
    共67頁: First 上一頁 37 38 39 40 41 42 43 44 45 下一頁 Last 
    主站蜘蛛池模板: 中文字幕看片在线a免费| 色多多A级毛片免费看| 四虎影视永久免费视频观看| 日韩成人免费视频| 女bbbbxxxx另类亚洲| 亚洲欧洲自拍拍偷综合| 亚洲成a人一区二区三区| 免费三级毛片电影片| 任你躁在线精品免费| 天天综合亚洲色在线精品| 亚洲av专区无码观看精品天堂| 亚洲人成无码网WWW| 国产免费无遮挡精品视频| 在线观看视频免费完整版| 亚洲视频在线观看免费视频| 国产一区二区三区亚洲综合 | 亚洲视频一区二区| 婷婷亚洲天堂影院| 免费夜色污私人影院在线观看| 午夜视频免费成人| 国产女高清在线看免费观看| 日韩一区二区免费视频| 成人免费无码视频在线网站| 成年网站免费视频A在线双飞| 国内精品免费麻豆网站91麻豆| 亚洲黄色免费网址| 蜜桃视频在线观看免费网址入口| 久久受www免费人成_看片中文| 无码中文在线二区免费| 四虎成人精品一区二区免费网站| 真实乱视频国产免费观看| 国产禁女女网站免费看| 国产亚洲精品国产| 亚洲五月综合网色九月色| 亚洲国产精品免费在线观看| 亚洲av无码专区在线| 一级毛片aa高清免费观看| 人人玩人人添人人澡免费| 国产在线观看片a免费观看| 国产一级淫片a视频免费观看| 亚洲精品无码不卡在线播HE|