Fix for: 6415637: PKCS#12 key stores with empty passwords

Weijun Wang weijun.wang at oracle.com
Mon Jun 20 20:49:53 PDT 2011


Hi Florian

Thanks for looking into this.

The following bug is for this special purpose:

    6879539: enable empty password support for pkcs12 keystore
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6879539

and it's now still in code review mode:

    http://cr.openjdk.java.net/~weijun/6879539/webrev.01/
    http://cr.openjdk.java.net/~weijun/6880619/webrev.00/

It seems our implementations are the same. At first sight, your codes 
seem to use "char{}" as default and "char{0}" as alternative. But then, 
in your updated derive() method, "char{}" goes to "byte{0,0}" and 
"char{0}" goes to "byte{}". Finally, "byte{0,0}" always becomes the 
default key for an empty password.

I think the sun.com still works for SCA/OCA. At least that's written on 
http://openjdk.java.net/contribute/.

Thanks
Max


On 06/20/2011 09:06 PM, Florian Weimer wrote:
> Hi,
>
> the patch below fixes two issues with PKCS#12 key stores:
>
> 1. The password and salt expansion resulted in a division by zero for
>     empty password strings.
>
> 2. Practically speaking, there are two different ways of deriving keys
>     from an empty passphrase: the terminating NUL character is required
>     by the specification, but is left out by some implementations
>     (including OpenJDK if the first bug is fixed).  OpenSSL tries to
>     decrypt with both encodings, and the patch implements that as well.
>     It is difficult to properly implement the retry behavior without
>     changing any interfaces, so this patch uses "\0" for the password
>     *without* a NUL terminator.  This is a bit confusing, but it ensures
>     that passing an empty string as the password creates a PKCS#12 store
>     which is compliant with the specification.
>
> Because of the division of zero issue, the second change does not
> actually change behavior.
>
> Presumably, this does not count as a small change, so BFK needs to sign
> a contributor agreement.  Is the sun.com email address still the right
> one to submit the scanned copy?
>
> Florian
>
> diff -r 77b101812a2e -r c49309b998ec src/share/classes/com/sun/crypto/provider/PBEKey.java
> --- a/src/share/classes/com/sun/crypto/provider/PBEKey.java	Tue Jun 14 13:16:19 2011 +0200
> +++ b/src/share/classes/com/sun/crypto/provider/PBEKey.java	Fri Jun 17 15:05:06 2011 +0200
> @@ -56,9 +56,12 @@
>               // Should allow an empty password.
>               passwd = new char[0];
>           }
> -        for (int i=0; i<passwd.length; i++) {
> -            if ((passwd[i]<  '\u0020') || (passwd[i]>  '\u007E')) {
> -                throw new InvalidKeySpecException("Password is not ASCII");
> +        // Accept "\0" to signify "zero-length password with no terminator".
> +        if (!(passwd.length == 1&&  passwd[0] == 0)) {
> +            for (int i=0; i<passwd.length; i++) {
> +        	if ((passwd[i]<  '\u0020') || (passwd[i]>  '\u007E')) {
> +        	    throw new InvalidKeySpecException("Password is not ASCII");
> +        	}
>               }
>           }
>           this.key = new byte[passwd.length];
> diff -r 77b101812a2e -r c49309b998ec src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
> --- a/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Tue Jun 14 13:16:19 2011 +0200
> +++ b/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Fri Jun 17 15:05:06 2011 +0200
> @@ -60,11 +60,15 @@
>
>       static byte[] derive(char[] chars, byte[] salt,
>                            int ic, int n, int type) {
> -        // Add in trailing NULL terminator.
> -        int length = chars.length*2;
> -        if (length != 0) {
> -            length += 2;
> -        }
> +        // Add in trailing NULL terminator.  Special case:
> +	// no terminator if password is "\0".
> +	int length = chars.length*2;
> +	if (length == 2&&  chars[0] == 0) {
> +	    chars = new char[0];
> +	    length = 0;
> +	} else
> +	    length += 2;
> +	
>           byte[] passwd = new byte[length];
>           for (int i = 0, j = 0; i<  chars.length; i++, j+=2) {
>               passwd[j] = (byte) ((chars[i]>>>  8)&  0xFF);
> @@ -133,6 +137,8 @@
>       }
>
>       private static void concat(byte[] src, byte[] dst, int start, int len) {
> +	if (src.length == 0)
> +	    return;
>           int loop = len / src.length;
>           int off, i;
>           for (i = 0, off = 0; i<  loop; i++, off += src.length)
> diff -r 77b101812a2e -r c49309b998ec src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
> --- a/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Tue Jun 14 13:16:19 2011 +0200
> +++ b/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java	Fri Jun 17 15:05:06 2011 +0200
> @@ -256,11 +256,25 @@
>           }
>
>           try {
> -            // Use JCE
> -            SecretKey skey = getPBEKey(password);
> -            Cipher cipher = Cipher.getInstance(algOid.toString());
> -            cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
> -            byte[] privateKeyInfo = cipher.doFinal(encryptedKey);
> +            byte[] privateKeyInfo;
> +            while (true) {
> +        	try {
> +        	    // Use JCE
> +        	    SecretKey skey = getPBEKey(password);
> +        	    Cipher cipher = Cipher.getInstance(algOid.toString());
> +        	    cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
> +        	    privateKeyInfo = cipher.doFinal(encryptedKey);
> +        	    break;
> +        	} catch (Exception e) {
> +        	    if (password.length == 0) {
> +        		// Retry using an empty password
> +        		// without a NULL terminator.
> +        		password = new char[1];
> +        		continue;
> +        	    }
> +        	    throw e;
> +        	}
> +            }
>
>               PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(privateKeyInfo);
>
> @@ -1272,18 +1286,26 @@
>                   ObjectIdentifier algOid = in.getOID();
>                   AlgorithmParameters algParams = parseAlgParameters(in);
>
> -                try {
> -                    // Use JCE
> -                    SecretKey skey = getPBEKey(password);
> -                    Cipher cipher = Cipher.getInstance(algOid.toString());
> -                    cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
> -                    safeContentsData = cipher.doFinal(safeContentsData);
> -
> -                } catch (Exception e) {
> -                    IOException ioe = new IOException("failed to decrypt safe"
> -                                        + " contents entry: " + e);
> -                    ioe.initCause(e);
> -                    throw ioe;
> +                while (true) {
> +                    try {
> +                	// Use JCE
> +                	SecretKey skey = getPBEKey(password);
> +                	Cipher cipher = Cipher.getInstance(algOid.toString());
> +                	cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
> +                	safeContentsData = cipher.doFinal(safeContentsData);
> +                	break;
> +                    } catch (Exception e) {
> +                	if (password.length == 0) {
> +                	    // Retry using an empty password
> +                	    // without a NULL terminator.
> +                	    password = new char[1];
> +                	    continue;
> +                	}
> +                	IOException ioe = new IOException(
> +                		"failed to decrypt safe contents entry: " + e);
> +                	ioe.initCause(e);
> +                	throw ioe;
> +                    }
>                   }
>               } else {
>                   throw new IOException("public key protected PKCS12" +
> diff -r 77b101812a2e -r c49309b998ec test/sun/security/pkcs12/Bug6415637.java
> --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
> +++ b/test/sun/security/pkcs12/Bug6415637.java	Fri Jun 17 15:05:06 2011 +0200
> @@ -0,0 +1,291 @@
> +import java.io.ByteArrayInputStream;
> +import java.math.BigInteger;
> +import java.security.KeyStore;
> +import java.security.cert.X509Certificate;
> +import java.security.interfaces.RSAPrivateCrtKey;
> +
> +/*
> + * @test
> + * @bug 6415637
> + * @summary Support PKCS#12 key stores protected with an empty password
> + * @author Florian Weimer
> + */
> +
> +public class Bug6415637 {
> +
> +    public static void main(String[] args) throws Exception {
> +	check(WITH_NULL);
> +	check(WITHOUT_NULL);
> +    }
> +
> +    private static void check(String encodedBlob) throws Exception {
> +	byte[] blob = new byte[encodedBlob.length() * 2];
> +	for (int i = 0; i<  blob.length; ) {
> +	    final char ch = encodedBlob.charAt(i / 2);
> +	    blob[i++] = (byte) (ch>>  8);
> +	    blob[i++] = (byte) ch;
> +	}
> +	KeyStore store = KeyStore.getInstance("PKCS12");
> +	store.load(new ByteArrayInputStream(blob), new char[0]);
> +	if (!store.aliases().nextElement().equals("test"))
> +	    throw new Exception("test alias not found");
> +	KeyStore.PrivateKeyEntry e =
> +	    (KeyStore.PrivateKeyEntry) store.getEntry("test",
> +		    new KeyStore.PasswordProtection(new char[0]));
> +	X509Certificate cert = (X509Certificate) e.getCertificateChain()[0];
> +	if (!cert.getSubjectDN().toString().equals("CN=Test Key"))
> +	    throw new Exception("invalid certificate subject DN");
> +	RSAPrivateCrtKey key = (RSAPrivateCrtKey) e.getPrivateKey();
> +	if (!key.getPublicExponent().equals(BigInteger.valueOf(65537)))
> +	    throw new Exception("invalid public exponent");
> +    }
> +
> +    private static final String WITH_NULL =
> +	"\u3082\u097c\u0201\u0330\u8209\u3606\u092a\u8648\u86f7\u0d01" +
> +	"\u0701\ua082\u0927\u0482\u0923\u3082\u091f\u3082\u0564\u0609" +
> +	"\u2a86\u4886\uf70d\u0107\u01a0\u8205\u5504\u8205\u5130\u8205" +
> +	"\u4d30\u8205\u4906\u0b2a\u8648\u86f7\u0d01\u0c0a\u0102\ua082" +
> +	"\u04fa\u3082\u04f6\u3028\u060a\u2a86\u4886\uf70d\u010c\u0103" +
> +	"\u301a\u0414\u8317\ucfd6\u89ab\uc03b\u79d6\u4c45\u1b10\uc3bd" +
> +	"\u3923\ub806\u0202\u0400\u0482\u04c8\ud51d\uf953\ud79e\u92c6" +
> +	"\u83c0\u92dc\ucd05\u69ab\ucc1b\ud538\u2ed9\u7796\ua426\uc14e" +
> +	"\udcbf\ue541\u40be\ud264\u3b5b\uf51f\u8e1a\u892f\u2813\ucdd6" +
> +	"\uf72e\uef55\u35ef\u4620\ude18\ued5e\ufae0\ubed4\uf84e\u276b" +
> +	"\u3596\uc33f\ub251\ue617\u6e00\ua80f\u6c82\u4acd\u7303\u26be" +
> +	"\uffb5\u1e49\u5fb1\uf87c\ua873\ue60a\u7415\u655c\u39f1\ucf16" +
> +	"\u8f5c\u85c6\u4100\u4130\u565b\u649a\u60d6\u6054\u868d\u7267" +
> +	"\u97a8\u8492\uc5a0\udb5e\u2880\udf55\ub0ee\ua641\u8224\u76d2" +
> +	"\u9b1e\u2a67\u1e32\ue1fc\u0a77\u435b\u669f\ued00\u6c30\u963f" +
> +	"\u7ee3\uc5c8\u198f\u8ede\u30e1\u015d\u1195\uc850\u3371\ub9e5" +
> +	"\u6968\u84c3\ub0e4\u22b7\u2a08\u4a9d\u9166\ua9ba\ud945\u0529" +
> +	"\ue1e7\u8aba\ub4ef\u7445\udc9a\ucf73\ud77b\ufafe\ue1df\u3180" +
> +	"\u9585\ued73\uca40\u06b0\ufdee\u95ba\u1aa3\ubd67\ua5c1\u84b4" +
> +	"\u4b50\uc1e1\u4547\ud837\u21bc\uac0d\u0a65\uebb5\u7281\ud9bc" +
> +	"\u2e2c\ua9bc\u7714\u0fc0\uab41\uce09\ud5e8\u5f8c\uc35d\uba6e" +
> +	"\u98a2\u95c3\u87ff\uba8c\u056a\udc9f\uf254\u3d38\uf40a\u77dd" +
> +	"\u4e30\u01de\ubef7\ud288\ue59c\ua143\ub30b\ud0ae\u63b9\u138b" +
> +	"\uc793\u3474\u18ca\udeed\u78d9\u2ae8\u63cc\ua5d1\u6779\u0229" +
> +	"\u7b72\ucfd4\ueecb\ue167\u08c0\u7556\u181d\u8d62\uc401\ub092" +
> +	"\u8cf5\ued71\uf29f\u843e\u13e1\u7e7b\uf589\u0329\u92bd\ud0e3" +
> +	"\u8dcc\u7541\uf195\ueef2\u3f3a\ueb01\uf5b0\u1869\u2216\uf351" +
> +	"\u488d\udffb\u6243\u1121\u9447\u8a3a\u006f\u008c\ue2b3\ued31" +
> +	"\u7f57\u6492\ue02f\u6f68\u387d\u58c0\uaadf\u2ee3\uf304\u3de9" +
> +	"\u9741\u47fa\udde8\ufe8a\u679a\u597d\u8c7c\u9c71\u570e\u1dbd" +
> +	"\ud555\ue853\uff63\u0fcb\u4b28\u3691\u33c8\uc31f\uc510\u6cba" +
> +	"\ud92c\u6462\u733a\u739e\uc792\ud861\u743e\u3bd3\u006b\u2276" +
> +	"\u9fb3\u0a31\u1eb3\ub97e\u4a80\uc076\uaabc\u35a0\u678d\u17c3" +
> +	"\ua225\ua77c\u7d9c\uef2d\u83e2\u6996\uba70\uf6f8\u79a1\u9399" +
> +	"\uc86b\u1cc5\ub2a5\u02c1\ud676\ua274\u4933\u6c60\u6832\ub0be" +
> +	"\u5354\u5af9\uae23\u0963\u722d\u9ad2\u4461\ub768\u2068\u0ccb" +
> +	"\u94fd\u88ac\u0f58\u3bc0\u212d\u30c8\u8860\uf7c9\u1dde\ub6b4" +
> +	"\u3549\u5bcd\ucf83\u9420\u3a40\u16ad\uc4d7\ucd87\ue73a\ue1c7" +
> +	"\u21df\u7f4f\u8659\u9f79\u5b36\uf206\uac66\uc9f3\u6336\u164d" +
> +	"\u9046\uf4d5\u285d\ufcd8\ubd55\u1fb9\ua533\u9101\u1e87\uc7b0" +
> +	"\u64e9\u3817\u216c\u8d41\uba51\u743a\uc74e\ue4ab\u2820\u972f" +
> +	"\ue191\u85b4\u0ea7\ud896\u23cf\u7df5\u1653\ua9f3\ub724\ucbc9" +
> +	"\u9738\ud2f8\u464e\ucf12\u99b8\u64e0\uf03b\u8d02\u85a8\uab52" +
> +	"\u8da3\uea34\ube99\ue5f8\u2b38\ub082\u399d\ue61e\u64a1\u7f90" +
> +	"\u26e9\ueb74\u6107\ufe2f\u82ca\u87a5\u3028\u8e1f\ue859\u61d4" +
> +	"\ud26d\u23a9\uaadc\u02a7\u8ab2\u43d4\uf6b9\udf7a\u8935\u45a4" +
> +	"\ufad6\ue7e4\u92b7\u35d7\u1044\u8ed3\u74ef\uaaa9\u713f\u6ebc" +
> +	"\u1158\u5e5c\u7522\ufe17\ua515\u59a1\u75dd\ue7ac\uafd9\u16a9" +
> +	"\u190e\u18fc\uc041\ufc9e\u3e16\u60c4\ufe51\u6d53\ufa52\u4c08" +
> +	"\uce2a\ue546\u017b\ud96b\ube18\u8cb9\udd50\ued40\u14b0\u7da1" +
> +	"\u2f2c\ubf9d\uc7c7\u1b73\ua155\ucaf8\ue54d\uebb0\u160a\ubd64" +
> +	"\u5ef7\ue1cf\u4633\u86c1\ubc91\u839d\ub148\u9f31\uf2b1\ud133" +
> +	"\u168f\u9374\u4667\u6aa9\u0482\ua2a6\ub5c0\ud9b7\ua070\uf6bd" +
> +	"\u16fe\u0f41\u986b\u3d33\u7cb9\u291d\u24f0\u704a\uc946\u10a2" +
> +	"\udbcf\u6c5f\u5a83\u5507\u036e\ube9f\uf60a\u9da8\u72dd\u23c9" +
> +	"\u8878\udd67\uf486\u1384\u751f\u4694\uee3c\udc2e\ud5d7\ud99a" +
> +	"\u5ee2\u5455\ub82d\u1837\u336d\u5724\u635b\ubd0b\u2e7c\u92be" +
> +	"\u2110\u9c0e\u1662\u43f6\u62ae\u32e3\uaea4\u1cc5\uadc0\u7511" +
> +	"\u6ad4\u0228\ue399\u5741\u2050\ue31a\u7dc8\uf6db\u67bb\u994a" +
> +	"\u5b5a\uaac6\u2210\u95b0\u462e\u0684\u335e\uac36\u7ab9\uab1e" +
> +	"\u0b75\u0f05\u74c5\ufcb3\ua0a5\ube7e\u45f8\u92d5\u3399\u7dd6" +
> +	"\uf96e\u7e01\u7823\u6690\u231c\u4c47\u2d10\u7e7f\u5eb8\u70dd" +
> +	"\u98d2\u6204\u3a92\u3990\u502b\u7cdb\u952a\ufa97\uea3b\ud990" +
> +	"\u436f\uf33a\u070d\u2aff\u7497\u2591\u37e4\ua590\ue7ba\u2c1e" +
> +	"\u53d9\u73fa\udc53\u944f\ua3a5\u5093\u33a4\uf080\u1193\u37f2" +
> +	"\u7642\ub033\u7f90\u9b44\uff89\ue6ef\u81be\u9e6e\u68a4\u5a00" +
> +	"\u9232\u4372\u40aa\u2748\u229d\u534d\u316b\u6e89\ufcb7\uff2e" +
> +	"\ub654\u1649\ucb13\u3c28\u4940\u43aa\uc07d\u247c\u313c\u3017" +
> +	"\u0609\u2a86\u4886\uf70d\u0109\u1431\u0a1e\u0800\u7400\u6500" +
> +	"\u7300\u7430\u2106\u092a\u8648\u86f7\u0d01\u0915\u3114\u0412" +
> +	"\u5469\u6d65\u2031\u3330\u3833\u3132\u3234\u3236\u3437\u3082" +
> +	"\u03b3\u0609\u2a86\u4886\uf70d\u0107\u06a0\u8203\ua430\u8203" +
> +	"\ua002\u0100\u3082\u0399\u0609\u2a86\u4886\uf70d\u0107\u0130" +
> +	"\u2806\u0a2a\u8648\u86f7\u0d01\u0c01\u0630\u1a04\u14de\ud8d8" +
> +	"\ua792\uf9d9\u6875\ua51d\u98ec\udf03\uc2b6\u5100\u8a02\u0204" +
> +	"\u0080\u8203\u6074\ub909\u3c60\ua522\ue4ac\u0f60\u2396\u7baa" +
> +	"\ud208\ub76c\u89a5\ue4ef\u205d\u2062\u4a5b\ua684\uceae\u01b9" +
> +	"\u1e7a\u6e03\ud996\u555a\u615b\uba70\u406f\u80a9\u901e\ua947" +
> +	"\u5b8f\u73f3\udea3\ud8b1\u9782\uac87\u231a\udcd2\u3ef0\u3a17" +
> +	"\u4092\u509f\u0e79\u4cd7\u8516\u5111\uebe1\u86e0\uc548\u5ffc" +
> +	"\u9a99\u11ed\uef13\u17af\u2707\u8984\u8770\u7064\u1943\u1dd3" +
> +	"\u45cf\u9f80\u65f8\u9b3e\u1f70\u6bd0\uc726\u5506\ufb20\u6bdc" +
> +	"\uba8c\u0b19\ucd01\ud0f0\u7040\udf63\u48a5\udf5f\u6559\u1b33" +
> +	"\ubdae\u8183\uc13f\ued10\ud6dc\ud0f0\u6a7f\ubc36\uc7ca\u320f" +
> +	"\u50b8\ud422\ufd99\u8843\u65e8\ue201\u843b\u64ee\ub891\u3ba2" +
> +	"\uecae\ufda0\u72d6\u8394\u2551\ufc44\u3778\u27c3\u061a\u6d3b" +
> +	"\ubd80\ue010\u06df\u39e7\u3d6a\u5ae2\u93fa\u4de4\u938f\u6f27" +
> +	"\ufd39\u4380\u60da\uf215\u79d4\uf6f1\ua02f\u959a\ua0ea\u1c38" +
> +	"\u80e3\u2744\u7506\u54b3\u77ad\u18ce\ucfec\u555e\u7bbe\u2e2f" +
> +	"\u9900\ub2ef\ua5b9\ubdf0\u5e15\ua681\u92c7\u4f86\u2e1a\ub893" +
> +	"\u01fc\u01d2\ub674\uff19\u04c3\ua1a0\u2cea\u72e0\ua8f1\u1358" +
> +	"\ube79\u7caa\u269d\u728a\ue435\u37bd\u6495\uc106\u8830\u9b17" +
> +	"\ue16d\uef78\uae2b\u5313\u1c96\uc0ee\u3098\ud743\ucd1c\u7407" +
> +	"\uf4f9\uee72\ub95e\u31e7\u6435\u0173\u0336\u93c5\u8a1b\u05b4" +
> +	"\u4359\uc4be\ud92b\u8d21\u83a9\u32b7\u6433\ua9bc\u27c2\ud842" +
> +	"\ua4f2\u81c5\ua86c\u2fd2\uba30\u53bd\uc277\u659f\u203b\u60e5" +
> +	"\u37f7\u0984\u31c2\u838a\u2107\u5840\u6411\u1b8d\u044e\ub0b6" +
> +	"\uf558\ue6d3\u62bb\u5464\uf83a\u4d5b\uf153\u9e18\ua353\ubd05" +
> +	"\uf204\ud543\u037d\ue5aa\u473a\ueb13\uac19\u0494\ua08e\u76c3" +
> +	"\ufbd7\u9f1c\u8ca9\u57ad\ud218\uc018\u67ac\u0ae9\ub559\ufe38" +
> +	"\u5641\uec0c\ue0ee\u606c\u1989\ue5a2\uff09\u8c61\u1386\ueb51" +
> +	"\u7cbd\u95cd\u80c5\u3532\u8605\u596d\u4cfd\u7797\u1e82\ud2fe" +
> +	"\uad6b\ua16e\ub6cf\u8fce\ud5a9\u207f\u1d0a\udabe\uc3a6\u5633" +
> +	"\u2023\u925f\u809f\uee7c\u5362\u5fd9\u8dfc\u6b5f\uc95b\u0ae9" +
> +	"\u7b26\u9e5b\u97e8\u9d6e\uaf91\u6d1a\u1d19\ufc27\u0815\uccbc" +
> +	"\u83d4\u2ce2\ue06e\u21a1\u88da\u09af\u9671\uc510\uac23\u398d" +
> +	"\ubea2\ua9a1\uf0d3\u490d\ub94b\u7ff7\u6636\ub1fa\u9b10\u1be3" +
> +	"\u179b\u6a8a\u4a6c\ude1f\u5da7\u7c02\u96ec\u70ac\u5045\udd2c" +
> +	"\u9f6d\uc37d\u5ba6\u4895\ue142\u0db9\uf2dc\uba2e\ud054\ud33e" +
> +	"\u1ed9\u144b\u5d85\u9156\u3a90\ue8cd\u0a01\u67f5\ua81b\u4f56" +
> +	"\u99dd\u4950\ua551\uacdb\udf31\u1f05\u7169\u3231\u0071\u80ec" +
> +	"\ua4e9\ud74e\u62cf\u8931\u11f1\uc925\u0319\uabd4\ufb86\u73c2" +
> +	"\u1479\u005b\uf05d\u4f8d\u44e4\u942b\ud338\ud05d\u2b3b\uf6f5" +
> +	"\udc0d\uf741\u798b\ud8e9\u36a5\u577b\u8a95\ud773\uffcb\u17b3" +
> +	"\u7174\u9616\u9b5e\ua577\u983c\u6e7a\u6cc8\u4a04\u042b\u503e" +
> +	"\ud744\ub65e\ue5de\ufa24\u8c71\u1127\ud47f\ud290\ufd4c\u5cbb" +
> +	"\u0e21\u77fd\u6553\ub82b\ucb49\u41e7\u8e3d\u4539\u925d\u6ba9" +
> +	"\uae47\u391c\ua79e\ub6e2\u7142\u7cb3\u02f5\u6495\u7a85\u2dea" +
> +	"\u787b\u22b7\u6ec2\uea8d\uf930\u3d30\u2130\u0906\u052b\u0e03" +
> +	"\u021a\u0500\u0414\ubfef\u99f5\u0bb0\uc9b3\uf96a\ue267\u6bc0" +
> +	"\u0202\u6d78\ub923\u0414\u5500\u095a\u2a04\u2d7e\u708d\u9779" +
> +	"\u9bdb\u2c4f\u82f2\uf89f\u0202\u0400";
> +
> +    private static final String WITHOUT_NULL =
> +	"\u3082\u097c\u0201\u0330\u8209\u3606\u092a\u8648\u86f7\u0d01" +
> +	"\u0701\ua082\u0927\u0482\u0923\u3082\u091f\u3082\u0564\u0609" +
> +	"\u2a86\u4886\uf70d\u0107\u01a0\u8205\u5504\u8205\u5130\u8205" +
> +	"\u4d30\u8205\u4906\u0b2a\u8648\u86f7\u0d01\u0c0a\u0102\ua082" +
> +	"\u04fa\u3082\u04f6\u3028\u060a\u2a86\u4886\uf70d\u010c\u0103" +
> +	"\u301a\u0414\ud258\ubbe7\ub641\ud196\u4969\u3c88\u70f1\u8c97" +
> +	"\u95b1\u8bf3\u0202\u0400\u0482\u04c8\u096a\u4686\uf519\u61da" +
> +	"\u1b3b\uebfd\u89b1\u044b\u3bd8\u79a7\ud022\ud880\ud173\ucde1" +
> +	"\ud2c1\u2c5d\u8ebb\u6bd4\u46db\ub90b\u04b9\ub091\ud1f3\ud468" +
> +	"\u3e93\u2c88\uca5a\u1c54\u5342\u1eca\u8565\ubbbd\ua022\u1ead" +
> +	"\ud0bb\u1a8c\u69cf\uf0f4\ucbfb\u488a\ube99\uf190\ue01c\ud87d" +
> +	"\u78ca\u9e5c\u82f9\u76ad\u811f\u37d0\u272b\u0481\u500c\u0a27" +
> +	"\u08d3\ub637\u3e39\u6db1\ubcba\ue354\u6924\ua9d5\u3555\u20d6" +
> +	"\u4c6b\u3189\u5f91\u382c\uf351\u4de2\ubade\u2a14\uea84\u16b6" +
> +	"\uf7f7\u36de\ubba6\ue952\u5f5d\u8243\u2318\ucf3d\u8ac8\u33d3" +
> +	"\u706c\ue3db\u6619\u7935\u7300\u89b3\u0bcd\uca9f\u0333\ua450" +
> +	"\u1be1\u3e42\ub465\uced5\ub055\u5843\uf40f\ua0f2\u6fea\u94fa" +
> +	"\ua51e\u4b5d\u93c9\ucb2e\u977e\uafd9\u2a2f\u784b\u0320\u5550" +
> +	"\u273f\u469f\uc42b\u2ce7\uedea\u4e0d\u54a5\u1a25\u4fac\ue346" +
> +	"\u2102\u7ab6\uea86\u554f\u7706\u8a80\uf6dd\u04f8\u3b37\u005a" +
> +	"\u4562\u2ef8\u59f9\u32b7\u31c0\ue7dc\ucbde\ue0e1\u2fd9\u0960" +
> +	"\u3e7a\ub4e5\u2a58\u1e2b\uef14\u9a44\u5444\u806d\uc475\u12ab" +
> +	"\ucc3d\ua03b\ubd52\ubf1c\ua9a6\u58aa\uee8b\u96c2\ud0c9\ua029" +
> +	"\u1db4\ub118\u4807\uecaa\ue182\uabb7\ud9ed\u66c5\u2c80\uc6a6" +
> +	"\u3f54\ubc73\u2632\ue1b0\u0d74\u001c\u5740\uc74b\ufadb\u25b4" +
> +	"\ua10e\u3191\u69e6\u0861\u452b\u955c\uac56\ud3c4\u86b7\u45f8" +
> +	"\u777a\uc336\u8cc7\ud471\u76b6\u11d8\ueb84\u14e4\uf44f\uc9ff" +
> +	"\u8929\u0d84\ubcfe\u8cc2\u9d07\u94e6\u1cf9\u19b5\u773a\u012d" +
> +	"\u0453\u4ff3\u40f2\ub144\ufc80\u571c\u0e13\uf890\u9fed\u2045" +
> +	"\u7baf\ufd88\u4920\u2b86\u491d\uecf8\ua5d9\u1e12\u48c7\u2c84" +
> +	"\u3fbe\u4df5\u11ce\u7b81\u83fc\u3efa\u697d\u1f3d\u8d81\u01b0" +
> +	"\u0bf1\u9012\u697f\u3b25\u3574\u5286\udded\u5be0\u7e92\u0a02" +
> +	"\ua486\ud19b\ue0b5\ua05c\u5ac2\u0ad5\u0d04\ua763\ub5c8\uf7e6" +
> +	"\u6e77\u2df3\ub9e7\uda30\ufccb\u7642\u5dc1\udf1f\uc922\uff69" +
> +	"\u4471\u4749\u937a\ud77d\u7c0d\u917c\uf2ef\u122c\u13b2\u8943" +
> +	"\u33aa\uad59\u86e8\u21c4\ueaa0\uf200\ue5f3\u6da0\ue8ef\uce7e" +
> +	"\u37b2\u3ddf\u0480\u08fc\uf89a\ud927\u3f5b\u75d3\ubdfe\u6ebd" +
> +	"\ufab1\u9f54\u1c20\u625b\u1391\u2af0\u43ba\u4395\udf22\u299e" +
> +	"\uf3bf\u7750\u5f68\u0120\u0ee0\u6960\ud939\u621f\uf845\u0025" +
> +	"\ue33c\u7ed9\ueadf\u0005\u6306\u7274\u5e67\ucf7a\uf3c6\u7371" +
> +	"\u487b\u79d7\u2142\ubc1a\ubfe4\u3536\u15db\ufe23\u4352\u6321" +
> +	"\u329d\uc251\u84c8\ufc0e\uc0ca\u5be6\uf530\u0177\ud9cb\ud132" +
> +	"\uf752\u3f26\uda90\ud9cf\u2e46\u3e09\u5d9a\u6902\udb3e\ub06c" +
> +	"\u722d\uf498\u3e93\u6cae\u43b5\u535a\u1cd1\uf0b2\u8d80\u9e53" +
> +	"\ue02e\uf782\u01ce\u5063\u73d1\u5571\uf0e7\ufa22\u7e48\u0c31" +
> +	"\u4642\u29fd\udcab\ue8d4\u7a77\u0880\u4855\u88c7\u7aa5\u0d9c" +
> +	"\uf8b7\uc91c\u127d\u2dd7\ude53\u9d3f\u132b\u965c\ubc80\udd97" +
> +	"\u87bf\ua0e8\ub2a2\u4e1f\u98fd\u72f3\u16ea\uc415\u5be3\ue8df" +
> +	"\u5681\u1f11\u4e3a\uac5d\u1684\u6602\ueb14\u0a96\ufcef\uaebf" +
> +	"\u1f2e\ud1a9\u435c\uf4e5\ub6b4\uaae2\u8244\u96a4\u0d3a\u752f" +
> +	"\uce21\u1bc9\u219e\uf17b\ud95e\ucd12\u1b0a\ucb85\ub0cd\u4ecb" +
> +	"\u6bb4\u5f7c\u2a93\ubb24\u9d7c\u6822\u80cd\u3f54\u78ad\u4fde" +
> +	"\ud57f\uec1d\ub54c\u0d78\u5946\u84c1\ua9ad\u0dea\u0292\ub279" +
> +	"\u1c76\u817e\ub910\ub1fa\ub1c0\u839d\u9eca\u6f83\u8211\u4112" +
> +	"\u440c\u4fbd\u6ef2\u897d\udfa9\ude9e\u1aef\u0f21\u26fb\uaca4" +
> +	"\u637e\ub072\u264f\ud24d\u9357\uc801\u0b84\u2d34\ueddf\u6063" +
> +	"\udc5d\u90dd\u5c62\ufb48\u8c5e\u7c4e\u3bdb\ub590\u7a75\udbd1" +
> +	"\udd78\uc8be\u5915\u7c8b\u8874\u578d\u3116\ub65a\uab8e\ud2ef" +
> +	"\u5d35\ubf8b\u2828\u8983\ua790\uedcf\u9698\ue023\u5786\u627b" +
> +	"\u9037\u1db7\u900e\u1f45\u0001\u7cf8\u14fd\ue437\u0dfd\ucacc" +
> +	"\u5edf\u1742\u7f6e\u612a\ud57d\udca0\u73a4\ud601\uc7f0\uca0e" +
> +	"\u5a44\u00b4\u233a\u84f2\u95b5\u5f16\uc291\u04fb\u369d\u6b99" +
> +	"\ue127\u493f\u66be\u86e9\u9672\u2849\u64a7\u851b\ue420\u8491" +
> +	"\ueb07\u6563\uc753\uc28e\ucad5\uec05\u6920\u8955\u5605\u25f6" +
> +	"\u6193\ubee5\u7a1a\ub73d\ucc27\uc8ce\u7179\u57c1\u7a2a\u37c1" +
> +	"\ua6c7\u2d8a\u4025\uc97d\u8c9d\u7b4b\u1ad5\uc6d7\u50fc\u246d" +
> +	"\u91a9\ua55d\u677a\udc83\u04c7\u3e14\u9950\u420c\udf02\u749b" +
> +	"\ude88\u5459\u2074\ua4ae\ud12d\uaf60\uba98\u630d\u313c\u3017" +
> +	"\u0609\u2a86\u4886\uf70d\u0109\u1431\u0a1e\u0800\u7400\u6500" +
> +	"\u7300\u7430\u2106\u092a\u8648\u86f7\u0d01\u0915\u3114\u0412" +
> +	"\u5469\u6d65\u2031\u3330\u3833\u3132\u3431\u3138\u3238\u3082" +
> +	"\u03b3\u0609\u2a86\u4886\uf70d\u0107\u06a0\u8203\ua430\u8203" +
> +	"\ua002\u0100\u3082\u0399\u0609\u2a86\u4886\uf70d\u0107\u0130" +
> +	"\u2806\u0a2a\u8648\u86f7\u0d01\u0c01\u0630\u1a04\u14af\ud4f5" +
> +	"\u0ff4\u0ede\u0da0\u6cc5\ufd9d\u3502\uae5e\u4cef\u3102\u0204" +
> +	"\u0080\u8203\u6028\ua7e6\u088b\u56b6\uf453\u9747\u68ec\uc064" +
> +	"\u2254\u693f\u25c5\uaa39\u3d87\uc97c\uc558\u5194\u7553\ude3a" +
> +	"\u4575\u9d85\ud843\u2bd0\ua2e8\u244f\u8593\uac84\u54b4\ubdc6" +
> +	"\ucea6\uba1a\ud3da\ua510\uee9d\uaf31\ub5c2\u3329\u0fed\u0e08" +
> +	"\u426b\u46fe\udcc5\u0979\ua9ed\u3123\u9a50\ud222\u3fc0\u771a" +
> +	"\u6f55\u9664\ud56f\u6b03\u6020\u78a4\u63b2\ue35e\u0816\u43a7" +
> +	"\u1909\u52e1\u8183\u1b8d\u9f5b\u19e4\uad73\u8461\ucc86\u3b49" +
> +	"\u322e\ue9d9\u3c66\uea22\u091e\u6621\ua8bf\u0169\u72d0\u535e" +
> +	"\u77dc\u1002\ubded\u7a91\u6cee\u58fa\uc295\uae8e\ue009\uabe9" +
> +	"\u6638\ucaea\u8bbf\uca27\udef5\u2881\u72ec\u8aa5\u582b\u9d6e" +
> +	"\u26bb\u3c70\u8bd6\uf5ec\u34ae\ua967\u5bb1\u22cb\u4b74\u0e50" +
> +	"\u5062\uc6f7\u7cb4\u58a3\uf43d\u57c0\u9654\u2f9c\u9308\u4546" +
> +	"\u6f4a\u37fe\u8d5d\u1465\u8621\u4cd8\u68d6\u0456\u96a4\ud3e2" +
> +	"\u76d1\u2675\u7654\u7649\u10e9\u9d0e\u8b04\uffb6\u020a\u2eb4" +
> +	"\uf24f\u150e\u7f0d\uf41b\u2c76\u538f\uc2df\u79dc\u0472\u1119" +
> +	"\uc148\ue2e8\u1820\ucd45\u08a7\u6bcd\u6eb0\ubd0a\ufff4\uec28" +
> +	"\u819b\u2adb\uefc8\ue8f7\ue233\u6535\uc938\u9771\u3681\u87cf" +
> +	"\u3a24\u4c71\ue1df\u3e19\u259c\uae5b\u27ed\u8a67\uf3e6\u7af0" +
> +	"\u48e1\uc542\uc471\ud8f4\ue317\u46e9\u0b4f\uec45\ua1d3\u2b88" +
> +	"\u8a22\udda1\u7c1a\u273c\ua0f7\u8bac\u3771\u28d2\u6ef8\u28d2" +
> +	"\ud83c\u196f\ue3fd\u9c79\u4305\u01b8\u3490\u0a91\ue4f3\uebc6" +
> +	"\u25a2\u7dd2\u72db\u7531\ucfca\u432f\u2beb\uc649\uf9c5\uc533" +
> +	"\u9f3a\ua611\u935c\ubca6\ud293\u54d6\u0dd1\u0aff\u82fb\u2d69" +
> +	"\u3da0\u3b33\u0986\u45b3\u3353\ub968\u7348\u454f\u9117\ub3dc" +
> +	"\ud7af\u06ca\ua34a\u9357\ue22f\uad3d\u4c76\ub386\ua8d7\u2a90" +
> +	"\u6d17\u9321\u7b00\u21e4\u1994\u9d18\u6439\u04c8\u8282\ub269" +
> +	"\uf786\u75c6\ua505\u983a\ua075\uffa0\ud662\u6ae5\ub126\u96d1" +
> +	"\u9e5e\u346b\ub7ee\ub0a3\u4ee8\ud204\u77ec\u2325\u5da8\ua326" +
> +	"\ua018\u0fd8\ue50e\u93cc\ucc40\u2d89\u2ffb\u54e0\u091a\u19fd" +
> +	"\u45d7\uc0ab\u77a2\u66ae\u794b\u6644\u21c3\ud782\u1e9e\u53e5" +
> +	"\u782e\u55e8\ud44e\u93e8\u379e\u5aa8\u353b\u95de\u7bc1\ucaf3" +
> +	"\u5223\ub5e9\uacbb\ub86b\u6014\u0626\ue7ad\ufd93\ue43a\ud864" +
> +	"\u1e6d\u14b2\ua12a\u94c5\u2ed9\ua7f7\u14f4\u0cbd\uca3b\u7c21" +
> +	"\ua85a\uf834\u6c99\ue1aa\u3832\u2515\u8170\u3c93\u7def\u94fe" +
> +	"\u9c3d\u4ab0\u73ed\u6c72\u8b94\ua407\uc719\uad1e\u6306\u4167" +
> +	"\u921e\uae53\u3fd4\uf569\u6f0b\u82b0\u0ca6\ud61f\ud526\u23c9" +
> +	"\u168d\u4baf\ucc4f\ud8a2\uc64a\ud649\u55e3\u7019\u8f20\u680c" +
> +	"\u5581\u2cb1\ub3a4\u3e37\u5fd3\ua3ca\uc115\u979c\uf910\u3797" +
> +	"\u05cb\u51d6\u74a4\uc5c0\u597b\uf27f\ud5e2\ue8ac\u4f3d\uc0c3" +
> +	"\u9594\u7799\u6876\ub1a3\u059a\uff03\uc2ee\uc8c2\uf224\u3720" +
> +	"\u9177\uabdb\u9202\u18d8\uffbe\u0516\u2a76\uedb5\ufe9e\u6d65" +
> +	"\u4c35\ue4cb\u75aa\u02be\ud24c\ua482\ufc67\ue4f9\u70c7\u3567" +
> +	"\ufc3f\uaa89\ue80a\u6507\u0a65\u4e18\uf919\u071d\u423c\u1756" +
> +	"\u30e5\u37f3\u19b3\u10fb\u6c30\u3d30\u2130\u0906\u052b\u0e03" +
> +	"\u021a\u0500\u0414\ufd05\u4444\ud347\u673c\u6da4\udb7c\u0733" +
> +	"\ud7bf\ud263\uc6b2\u0414\udd17\u155e\u2d4c\u25cb\ua028\u1a23" +
> +	"\ub8b0\uf6be\u925f\ude3a\u0202\u0400";
> +
> +}
>
>



More information about the security-dev mailing list