Android中的簽名機制

Android中籤名用的Key的產生方法和簽名的原理。

產生Key

產生RSA私鑰(private key)
openssl genrsa -3 -out testkey.pem 2048
-3 是算法的參數(public exponent)。
2048 是私鑰長度。
testkey.pem 是輸出的文件。


產生PKCS#10格式的認證請求。所謂認證請求就是發給認證機構認證的一個請求,它主要包括一個公鑰和一些相關信息(如組織名稱和聯繫人郵件地址)。
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 /
-subj ‘/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]


如果不提供最後兩個參數,openssl會提示你輸入相關信息,這裏的信息可以根據你自己的實際情況填寫。如


openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [GB]:CN
State or Province Name (full name) [Berkshire]:GuangDong
Locality Name (eg, city) [Newbury]:ShenZhen
Organization Name (eg, company) [My Company Ltd]:Topwise
Organizational Unit Name (eg, section) []:Broncho
Common Name (eg, your name or your server’s hostname) []:broncho.cn
Email Address []:[email protected]


把私鑰的格式轉換成PKCS #8(Private-Key Information Syntax Standard.)

openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt

私鑰是不能讓別人知道的,否則就起不到保密的作用了。私鑰通常是要加密保存的,但這裏指定了-nocryp,表示不加密

Android提供了一個腳本mkkey.sh用來簡化上面的步驟:

if ["$1" == ""]; then
    echo "Create a test certificate key."
    echo "Usage: $0 NAME"
    echo "Will generate NAME.pk8 and NAME.x509.pem"
    echo "  /C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]"
    return
fi
 
openssl genrsa -3 -out $1.pem 2048
 
openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 /
    -subj '/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]'
 
openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt


簽名

Android提供了爲jar/zip文件簽名的程序signapk.jar 。

它的用法如下:
Usage: signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar

第一個參數是公鑰,即前面第二步產生的testkey.x509.pem。
第二個參數是私鑰,即前面第三步產生的testkey.pk8。
第三個參數是要簽名的文件。
第四個參數是輸出的文件(即簽名後的文件)。


如:java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip update-signed.zip

現在我們來看看簽名到底做了些什麼:

 先爲輸入的jar/zip文件中的所有文件生成SHA1數字簽名(除了CERT.RSA,CERT.SF和MANIFEST.MF)

      
 for (JarEntry entry: byName.values()) {
            String name = entry.getName();
            if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) &&
                !name.equals(CERT_SF_NAME) && !name.equals(CERT_RSA_NAME) &&
                (stripPattern == null ||
                 !stripPattern.matcher(name).matches())) {
                InputStream data = jar.getInputStream(entry);
                while ((num = data.read(buffer)) > 0) {
                    md.update(buffer, 0, num);
                }
 
                Attributes attr = null;
                if (input != null) attr = input.getAttributes(name);
                attr = attr != null ? new Attributes(attr) : new Attributes();
                attr.putValue("SHA1-Digest", base64.encode(md.digest()));
                output.getEntries().put(name, attr);
            }
        }



並把數字簽名信息寫入MANIFEST.MF

     
 je = new JarEntry(JarFile.MANIFEST_NAME);
            je.setTime(timestamp);
            outputJar.putNextEntry(je);
            manifest.write(outputJar);

     

對manifest簽名並寫入CERT.SF

           
// CERT.SF
            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initSign(privateKey);
            je = new JarEntry(CERT_SF_NAME);
            je.setTime(timestamp);
            outputJar.putNextEntry(je);
            writeSignatureFile(manifest,
            new SignatureOutputStream(outputJar, signature));



把對輸出文件的簽名和公鑰寫入CERT.RSA。


            // CERT.RSA
            je = new JarEntry(CERT_RSA_NAME);
            je.setTime(timestamp);
            outputJar.putNextEntry(je);
            writeSignatureBlock(signature, publicKey, outputJar);



簽名的作用

簽名的主要目的爲了檢測文件是否被別人修改了。但它並不能禁止別人修改,因爲你完全重新生成簽名,但是你生成的簽名和原來是不一樣的。

http://blog.csdn.net/absurd/article/details/5002763

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章