提交 d31ac944 编写于 作者: W weijun

6862679: ESC: AD Authentication with user with umlauts fails

Reviewed-by: valeriep, mullan
上级 8864bc3c
......@@ -33,16 +33,11 @@ package sun.security.krb5;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.ccache.CredentialsCache;
import java.util.StringTokenizer;
import sun.security.krb5.internal.ktab.*;
import sun.security.krb5.internal.crypto.EType;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Vector;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
/**
......@@ -378,9 +373,9 @@ public class Credentials {
KRBError error = ke.getError();
// update salt in PrincipalName
byte[] newSalt = error.getSalt();
if (newSalt != null && newSalt.length > 0) {
princ.setSalt(new String(newSalt));
String newSalt = error.getSalt();
if (newSalt != null && newSalt.length() > 0) {
princ.setSalt(newSalt);
}
// refresh keys
......
/*
* Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -56,7 +56,7 @@ public class KrbAsReq extends KrbKdcReq {
private boolean PA_ENC_TIMESTAMP_REQUIRED = false;
private boolean pa_exists = false;
private int pa_etype = 0;
private byte[] pa_salt = null;
private String pa_salt = null;
private byte[] pa_s2kparams = null;
// default is address-less tickets
......@@ -88,7 +88,7 @@ public class KrbAsReq extends KrbKdcReq {
* with pre-authentication values
*/
KrbAsReq(PrincipalName principal, EncryptionKey[] keys,
boolean pa_exists, int etype, byte[] salt, byte[] s2kparams)
boolean pa_exists, int etype, String salt, byte[] s2kparams)
throws KrbException, IOException {
this(keys, // for pre-authentication
pa_exists, etype, salt, s2kparams, // pre-auth values
......@@ -112,7 +112,7 @@ public class KrbAsReq extends KrbKdcReq {
}
// update with pre-auth info
public void updatePA(int etype, byte[] salt, byte[] params, PrincipalName name) {
public void updatePA(int etype, String salt, byte[] params, PrincipalName name) {
// set the pre-auth values
pa_exists = true;
pa_etype = etype;
......@@ -120,9 +120,8 @@ public class KrbAsReq extends KrbKdcReq {
pa_s2kparams = params;
// update salt in PrincipalName
if (salt != null && salt.length > 0) {
String newSalt = new String(salt);
name.setSalt(newSalt);
if (salt != null && salt.length() > 0) {
name.setSalt(salt);
if (DEBUG) {
System.out.println("Updated salt from pre-auth = " + name.getSalt());
}
......@@ -161,7 +160,7 @@ public class KrbAsReq extends KrbKdcReq {
char[] password,
boolean pa_exists,
int etype,
byte[] salt,
String salt,
byte[] s2kparams,
KDCOptions options,
PrincipalName cname,
......@@ -246,7 +245,7 @@ public class KrbAsReq extends KrbKdcReq {
EncryptionKey[] keys,
boolean pa_exists,
int etype,
byte[] salt,
String salt,
byte[] s2kparams,
KDCOptions options,
PrincipalName cname,
......
......@@ -38,6 +38,7 @@ import java.util.Vector;
import java.io.IOException;
import java.math.BigInteger;
import sun.security.krb5.internal.ccache.CCacheOutputStream;
import sun.security.krb5.internal.util.KerberosString;
/**
......@@ -246,7 +247,7 @@ public class PrincipalName
DerValue subSubDer;
while(subDer.getData().available() > 0) {
subSubDer = subDer.getData().getDerValue();
v.addElement(subSubDer.getGeneralString());
v.addElement(new KerberosString(subSubDer).toString());
}
if (v.size() > 0) {
nameStrings = new String[v.size()];
......@@ -554,7 +555,7 @@ public class PrincipalName
temp = new DerOutputStream();
DerValue der[] = new DerValue[nameStrings.length];
for (int i = 0; i < nameStrings.length; i++) {
der[i] = new DerValue(DerValue.tag_GeneralString, nameStrings[i]);
der[i] = new KerberosString(nameStrings[i]).toDerValue();
}
temp.putSequence(der);
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp);
......
......@@ -31,11 +31,6 @@
package sun.security.krb5;
import sun.security.krb5.Config;
import sun.security.krb5.PrincipalName;
import sun.security.krb5.KrbException;
import sun.security.krb5.Asn1Exception;
import sun.security.krb5.RealmException;
import sun.security.krb5.internal.Krb5;
import sun.security.util.*;
import java.io.IOException;
......@@ -43,6 +38,7 @@ import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Stack;
import java.util.EmptyStackException;
import sun.security.krb5.internal.util.KerberosString;
/**
* Implements the ASN.1 Realm type.
......@@ -109,7 +105,7 @@ public class Realm implements Cloneable {
if (encoding == null) {
throw new IllegalArgumentException("encoding can not be null");
}
realm = encoding.getGeneralString();
realm = new KerberosString(encoding).toString();
if (realm == null || realm.length() == 0)
throw new RealmException(Krb5.REALM_NULL);
if (!isValidRealmString(realm))
......@@ -206,7 +202,7 @@ public class Realm implements Cloneable {
*/
public byte[] asn1Encode() throws Asn1Exception, IOException {
DerOutputStream out = new DerOutputStream();
out.putGeneralString(this.realm);
out.putDerValue(new KerberosString(this.realm).toDerValue());
return out.toByteArray();
}
......
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,6 +28,7 @@ package sun.security.krb5.internal;
import sun.security.util.*;
import sun.security.krb5.Asn1Exception;
import java.io.IOException;
import sun.security.krb5.internal.util.KerberosString;
/**
* Implements the ASN.1 ETYPE-INFO-ENTRY type.
......@@ -43,7 +44,7 @@ import java.io.IOException;
public class ETypeInfo {
private int etype;
private byte[] salt = null;
private String salt = null;
private static final byte TAG_TYPE = 0;
private static final byte TAG_VALUE = 1;
......@@ -51,21 +52,13 @@ public class ETypeInfo {
private ETypeInfo() {
}
public ETypeInfo(int etype, byte[] salt) {
public ETypeInfo(int etype, String salt) {
this.etype = etype;
if (salt != null) {
this.salt = salt.clone();
}
this.salt = salt;
}
public Object clone() {
ETypeInfo etypeInfo = new ETypeInfo();
etypeInfo.etype = etype;
if (salt != null) {
etypeInfo.salt = new byte[salt.length];
System.arraycopy(salt, 0, etypeInfo.salt, 0, salt.length);
}
return etypeInfo;
return new ETypeInfo(etype, salt);
}
/**
......@@ -94,7 +87,22 @@ public class ETypeInfo {
if (encoding.getData().available() > 0) {
der = encoding.getData().getDerValue();
if ((der.getTag() & 0x1F) == 0x01) {
this.salt = der.getData().getOctetString();
byte[] saltBytes = der.getData().getOctetString();
// Although salt is defined as an OCTET STRING, it's the
// encoding from of a string. As RFC 4120 says:
//
// "The salt, ..., is also completely unspecified with respect
// to character set and is probably locale-specific".
//
// It's known that this field is using the same encoding as
// KerberosString in most implementations.
if (KerberosString.MSNAME) {
this.salt = new String(saltBytes, "UTF8");
} else {
this.salt = new String(saltBytes);
}
}
}
......@@ -120,7 +128,11 @@ public class ETypeInfo {
if (salt != null) {
temp = new DerOutputStream();
temp.putOctetString(salt);
if (KerberosString.MSNAME) {
temp.putOctetString(salt.getBytes("UTF8"));
} else {
temp.putOctetString(salt.getBytes());
}
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
TAG_VALUE), temp);
}
......@@ -135,8 +147,8 @@ public class ETypeInfo {
return etype;
}
public byte[] getSalt() {
return ((salt == null) ? null : salt.clone());
public String getSalt() {
return salt;
}
}
/*
* Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,6 +28,7 @@ package sun.security.krb5.internal;
import sun.security.util.*;
import sun.security.krb5.Asn1Exception;
import java.io.IOException;
import sun.security.krb5.internal.util.KerberosString;
/**
* Implements the ASN.1 ETYPE-INFO-ENTRY type.
......@@ -54,11 +55,9 @@ public class ETypeInfo2 {
private ETypeInfo2() {
}
public ETypeInfo2(int etype, byte[] salt, byte[] s2kparams) {
public ETypeInfo2(int etype, String salt, byte[] s2kparams) {
this.etype = etype;
if (salt != null) {
this.saltStr = new String(salt);
}
this.saltStr = salt;
if (s2kparams != null) {
this.s2kparams = s2kparams.clone();
}
......@@ -102,7 +101,8 @@ public class ETypeInfo2 {
if (encoding.getData().available() > 0) {
if ((encoding.getData().peekByte() & 0x1F) == 0x01) {
der = encoding.getData().getDerValue();
this.saltStr = der.getData().getGeneralString();
this.saltStr = new KerberosString(
der.getData().getDerValue()).toString();
}
}
......@@ -136,7 +136,7 @@ public class ETypeInfo2 {
if (saltStr != null) {
temp = new DerOutputStream();
temp.putGeneralString(saltStr);
temp.putDerValue(new KerberosString(saltStr).toDerValue());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
TAG_VALUE1), temp);
}
......@@ -157,8 +157,8 @@ public class ETypeInfo2 {
return etype;
}
public byte[] getSalt() {
return ((saltStr == null) ? null : saltStr.getBytes());
public String getSalt() {
return saltStr;
}
public byte[] getParams() {
......
/*
* Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -42,6 +42,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.util.Arrays;
import sun.security.krb5.internal.util.KerberosString;
/**
* Implements the ASN.1 KRBError type.
*
......@@ -97,7 +98,7 @@ public class KRBError implements java.io.Serializable {
// pre-auth info
private int etype = 0;
private byte[] salt = null;
private String salt = null;
private byte[] s2kparams = null;
private static boolean DEBUG = Krb5.DEBUG;
......@@ -334,8 +335,8 @@ public class KRBError implements java.io.Serializable {
}
// access pre-auth info
public final byte[] getSalt() {
return ((salt == null) ? null : salt.clone());
public final String getSalt() {
return salt;
}
// access pre-auth info
......@@ -415,7 +416,8 @@ public class KRBError implements java.io.Serializable {
if (der.getData().available() >0) {
if ((der.getData().peekByte() & 0x1F) == 0x0B) {
subDer = der.getData().getDerValue();
eText = subDer.getData().getGeneralString();
eText = new KerberosString(subDer.getData().getDerValue())
.toString();
}
}
if (der.getData().available() >0) {
......@@ -515,7 +517,7 @@ public class KRBError implements java.io.Serializable {
if (eText != null) {
temp = new DerOutputStream();
temp.putGeneralString(eText);
temp.putDerValue(new KerberosString(eText).toDerValue());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x0B), temp);
}
if (eData != null) {
......
......@@ -34,17 +34,29 @@ import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import java.security.Security;
import java.security.Provider;
import java.security.GeneralSecurityException;
import javax.crypto.spec.IvParameterSpec;
import sun.security.krb5.KrbCryptoException;
import sun.security.krb5.internal.Krb5;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import sun.security.action.GetPropertyAction;
public final class Des {
// RFC 3961 demands that UTF-8 encoding be used in DES's
// string-to-key function. For historical reasons, some
// implementations use a locale-specific encoding. Even
// so, when the client and server use different locales,
// they must agree on a common value, normally the one
// used when the password is set/reset.
//
// The following system property is provided to perform the
// string-to-key encoding. When set, the specified charset
// name is used. Otherwise, the system default charset.
private final static String CHARSET =
java.security.AccessController.doPrivileged(
new GetPropertyAction("sun.security.krb5.msinterop.des.s2kcharset"));
private static final long[] bad_keys = {
0x0101010101010101L, 0xfefefefefefefefeL,
0x1f1f1f1f1f1f1f1fL, 0xe0e0e0e0e0e0e0e0L,
......@@ -226,7 +238,11 @@ public final class Des {
// Convert password to byte array
try {
cbytes = (new String(passwdChars)).getBytes();
if (CHARSET == null) {
cbytes = (new String(passwdChars)).getBytes();
} else {
cbytes = (new String(passwdChars)).getBytes(CHARSET);
}
} catch (Exception e) {
// clear-up sensitive information
if (cbytes != null) {
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.security.krb5.internal.util;
import java.io.IOException;
import java.security.AccessController;
import sun.security.action.GetBooleanAction;
import sun.security.util.DerValue;
/**
* Implements the ASN.1 KerberosString type.
*
* <pre>
* KerberosString ::= GeneralString (IA5String)
* </pre>
*
* This definition reflects the Network Working Group RFC 4120
* specification available at
* <a href="http://www.ietf.org/rfc/rfc4120.txt">
* http://www.ietf.org/rfc/rfc4120.txt</a>.
*/
public final class KerberosString {
/**
* RFC 4120 defines KerberosString as GeneralString (IA5String), which
* only includes ASCII characters. However, other implementations have been
* known to use GeneralString to contain UTF-8 encoding. To interop
* with these implementations, the following system property is defined.
* When set as true, KerberosString is encoded as UTF-8. Note that this
* only affects the byte encoding, the tag of the ASN.1 type is still
* GeneralString.
*/
public static final boolean MSNAME = AccessController.doPrivileged(
new GetBooleanAction("sun.security.krb5.msinterop.kstring"));
private final String s;
public KerberosString(String s) {
this.s = s;
}
public KerberosString(DerValue der) throws IOException {
if (der.tag != DerValue.tag_GeneralString) {
throw new IOException(
"KerberosString's tag is incorrect: " + der.tag);
}
s = new String(der.getDataBytes(), MSNAME?"UTF8":"ASCII");
}
public String toString() {
return s;
}
public DerValue toDerValue() throws IOException {
// No need to cache the result since this method is
// only called once.
return new DerValue(DerValue.tag_GeneralString,
s.getBytes(MSNAME?"UTF8":"ASCII"));
}
}
/*
* Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -252,15 +252,15 @@ public class Kinit {
}
KRBError error = ke.getError();
int etype = error.getEType();
byte[] salt = error.getSalt();
String salt = error.getSalt();
byte[] s2kparams = error.getParams();
if (useKeytab) {
as_req = new KrbAsReq(skeys, true, etype, salt, s2kparams,
opt, principal, sname,
as_req = new KrbAsReq(skeys, true, etype, salt,
s2kparams, opt, principal, sname,
null, null, null, null, addresses, null);
} else {
as_req = new KrbAsReq(psswd, true, etype, salt, s2kparams,
opt, principal, sname,
as_req = new KrbAsReq(psswd, true, etype, salt,
s2kparams, opt, principal, sname,
null, null, null, null, addresses, null);
}
as_rep = sendASRequest(as_req, useKeytab, realm, psswd, skeys);
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6862679
* @summary ESC: AD Authentication with user with umlauts fails
*/
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import sun.security.krb5.EncryptedData;
import sun.security.krb5.internal.crypto.Des;
import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.crypto.crc32;
import sun.security.krb5.internal.crypto.dk.AesDkCrypto;
import sun.security.krb5.internal.crypto.dk.Des3DkCrypto;
import sun.security.krb5.internal.crypto.dk.DkCrypto;
import java.nio.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class RFC396xTest {
static final String gclef = new String(Character.toChars(0x1d11e));
/** Creates a new instance of NewClass */
public static void main(String[] args) throws Exception {
System.setProperty("sun.security.krb5.msinterop.des.s2kcharset",
"utf-8");
test();
}
static void test() throws Exception {
// RFC 3961
// A.1
Method nfold = DkCrypto.class.getDeclaredMethod("nfold", byte[].class, Integer.TYPE);
nfold.setAccessible(true);
assertStringEquals(hex((byte[])nfold.invoke(null, "012345".getBytes("UTF-8"), 64)), "be072631276b1955");
assertStringEquals(hex((byte[])nfold.invoke(null, "password".getBytes("UTF-8"), 56)), "78a07b6caf85fa");
assertStringEquals(hex((byte[])nfold.invoke(null, "Rough Consensus, and Running Code".getBytes("UTF-8"), 64)), "bb6ed30870b7f0e0");
assertStringEquals(hex((byte[])nfold.invoke(null, "password".getBytes("UTF-8"), 168)), "59e4a8ca7c0385c3c37b3f6d2000247cb6e6bd5b3e");
assertStringEquals(hex((byte[])nfold.invoke(null, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY".getBytes("UTF-8"), 192)), "db3b0d8f0b061e603282b308a50841229ad798fab9540c1b");
assertStringEquals(hex((byte[])nfold.invoke(null, "Q".getBytes("UTF-8"), 168)), "518a54a215a8452a518a54a215a8452a518a54a215");
assertStringEquals(hex((byte[])nfold.invoke(null, "ba".getBytes("UTF-8"), 168)), "fb25d531ae8974499f52fd92ea9857c4ba24cf297e");
assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 64)), "6b65726265726f73");
assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 128)), "6b65726265726f737b9b5b2b93132b93");
assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 168)), "8372c236344e5f1550cd0747e15d62ca7a5a3bcea4");
assertStringEquals(hex((byte[])nfold.invoke(null, "kerberos".getBytes("UTF-8"), 256)), "6b65726265726f737b9b5b2b93132b935c9bdcdad95c9899c4cae4dee6d6cae4");
// A.2
assertStringEquals(hex(Des.string_to_key_bytes("passwordATHENA.MIT.EDUraeburn".toCharArray())), "cbc22fae235298e3");
assertStringEquals(hex(Des.string_to_key_bytes("potatoeWHITEHOUSE.GOVdanny".toCharArray())), "df3d32a74fd92a01");
assertStringEquals(hex(Des.string_to_key_bytes((gclef+"EXAMPLE.COMpianist").toCharArray())), "4ffb26bab0cd9413");
assertStringEquals(hex(Des.string_to_key_bytes("\u00dfATHENA.MIT.EDUJuri\u0161i\u0107".toCharArray())), "62c81a5232b5e69d");
// Next 2 won't pass, since there's no real weak key here
//assertStringEquals(hex(Des.string_to_key_bytes("11119999AAAAAAAA".toCharArray())), "984054d0f1a73e31");
//assertStringEquals(hex(Des.string_to_key_bytes("NNNN6666FFFFAAAA".toCharArray())), "c4bf6b25adf7a4f8");
// A.3
Object o = Des3DkCrypto.class.getConstructor().newInstance();
Method dr = DkCrypto.class.getDeclaredMethod("dr", byte[].class, byte[].class);
Method randomToKey = DkCrypto.class.getDeclaredMethod("randomToKey", byte[].class);
dr.setAccessible(true);
randomToKey.setAccessible(true);
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("dce06b1f64c857a11c3db57c51899b2cc1791008ce973b92"),
xeh("0000000155")))),
"925179d04591a79b5d3192c4a7e9c289b049c71f6ee604cd");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("5e13d31c70ef765746578531cb51c15bf11ca82c97cee9f2"),
xeh("00000001aa")))),
"9e58e5a146d9942a101c469845d67a20e3c4259ed913f207");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("98e6fd8a04a4b6859b75a176540b9752bad3ecd610a252bc"),
xeh("0000000155")))),
"13fef80d763e94ec6d13fd2ca1d085070249dad39808eabf");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("622aec25a2fe2cad7094680b7c64940280084c1a7cec92b5"),
xeh("00000001aa")))),
"f8dfbf04b097e6d9dc0702686bcb3489d91fd9a4516b703e");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("d3f8298ccb166438dcb9b93ee5a7629286a491f838f802fb"),
xeh("6b65726265726f73")))),
"2370da575d2a3da864cebfdc5204d56df779a7df43d9da43");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("c1081649ada74362e6a1459d01dfd30d67c2234c940704da"),
xeh("0000000155")))),
"348057ec98fdc48016161c2a4c7a943e92ae492c989175f7");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("5d154af238f46713155719d55e2f1f790dd661f279a7917c"),
xeh("00000001aa")))),
"a8808ac267dada3dcbe9a7c84626fbc761c294b01315e5c1");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("798562e049852f57dc8c343ba17f2ca1d97394efc8adc443"),
xeh("0000000155")))),
"c813f88a3be3b334f75425ce9175fbe3c8493b89c8703b49");
assertStringEquals(hex((byte[])randomToKey.invoke(o, (byte[])dr.invoke(o,
xeh("26dce334b545292f2feab9a8701a89a4b99eb9942cecd016"),
xeh("00000001aa")))),
"f48ffd6e83f83e7354e694fd252cf83bfe58f7d5ba37ec5d");
// A.4
assertStringEquals(hex(new Des3DkCrypto().stringToKey("passwordATHENA.MIT.EDUraeburn".toCharArray())), "850bb51358548cd05e86768c313e3bfef7511937dcf72c3e");
assertStringEquals(hex(new Des3DkCrypto().stringToKey("potatoeWHITEHOUSE.GOVdanny".toCharArray())), "dfcd233dd0a43204ea6dc437fb15e061b02979c1f74f377a");
assertStringEquals(hex(new Des3DkCrypto().stringToKey("pennyEXAMPLE.COMbuckaroo".toCharArray())), "6d2fcdf2d6fbbc3ddcadb5da5710a23489b0d3b69d5d9d4a");
assertStringEquals(hex(new Des3DkCrypto().stringToKey("\u00DFATHENA.MIT.EDUJuri\u0161i\u0107".toCharArray())), "16d5a40e1ce3bacb61b9dce00470324c831973a7b952feb0");
assertStringEquals(hex(new Des3DkCrypto().stringToKey((gclef+"EXAMPLE.COMpianist").toCharArray())), "85763726585dbc1cce6ec43e1f751f07f1c4cbb098f40b19");
// A.5
assertStringEquals(hex(crc32.byte2crc32sum_bytes("foo".getBytes("UTF-8"))), "33bc3273");
assertStringEquals(hex(crc32.byte2crc32sum_bytes("test0123456789".getBytes("UTF-8"))), "d6883eb8");
assertStringEquals(hex(crc32.byte2crc32sum_bytes("MASSACHVSETTS INSTITVTE OF TECHNOLOGY".getBytes("UTF-8"))), "f78041e3");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80, 0})), "4b98833b");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, 8})), "3288db0e");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, (byte)0x80})), "2083b8ed");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80})), "2083b8ed");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {(byte)0x80, 0, 0, 0})), "3bb659ed");
assertStringEquals(hex(crc32.byte2crc32sum_bytes(new byte[] {0, 0, 0, 1})), "96300777");
// RFC 3962
AesDkCrypto a1 = new AesDkCrypto(128);
Method pbkdf2 = AesDkCrypto.class.getDeclaredMethod("PBKDF2", char[].class, byte[].class, Integer.TYPE, Integer.TYPE);
Method s2k = AesDkCrypto.class.getDeclaredMethod("stringToKey", char[].class, byte[].class, byte[].class);
pbkdf2.setAccessible(true);
s2k.setAccessible(true);
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1, 128)), "cd ed b5 28 1b b2 f8 01 56 5a 11 22 b2 56 35 15");
assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1))), "42 26 3c 6e 89 f4 fc 28 b8 df 68 ee 09 79 9f 15");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1, 256)), "cd ed b5 28 1b b2 f8 01 56 5a 11 22 b2 56 35 15 0a d1 f7 a0 4b b9 f3 a3 33 ec c0 e2 e1 f7 08 37");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 2, 128)), "01 db ee 7f 4a 9e 24 3e 98 8b 62 c7 3c da 93 5d");
assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(2))), "c6 51 bf 29 e2 30 0a c2 7f a4 69 d6 93 bd da 13");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 2, 256)), "01 db ee 7f 4a 9e 24 3e 98 8b 62 c7 3c da 93 5d a0 53 78 b9 32 44 ec 8f 48 a9 9e 61 ad 79 9d 86");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1200, 128)), "5c 08 eb 61 fd f7 1e 4e 4e c3 cf 6b a1 f5 51 2b");
assertStringEquals(hex(a1.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1200))), "4c 01 cd 46 d6 32 d0 1e 6d be 23 0a 01 ed 64 2a");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), "ATHENA.MIT.EDUraeburn".getBytes("UTF-8"), 1200, 256)), "5c 08 eb 61 fd f7 1e 4e 4e c3 cf 6b a1 f5 51 2b a7 e5 2d db c5 e5 14 2f 70 8a 31 e2 e6 2b 1e 13");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), xeh("1234567878563412"), 5, 128)), "d1 da a7 86 15 f2 87 e6 a1 c8 b1 20 d7 06 2a 49");
assertStringEquals(hex((byte[])s2k.invoke(a1, "password".toCharArray(), xeh("1234567878563412"), i2b(5))), "e9 b2 3d 52 27 37 47 dd 5c 35 cb 55 be 61 9d 8e");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "password".toCharArray(), xeh("1234567878563412"), 5, 256)), "d1 da a7 86 15 f2 87 e6 a1 c8 b1 20 d7 06 2a 49 3f 98 d2 03 e6 be 49 a6 ad f4 fa 57 4b 6e 64 ee");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size".getBytes("UTF-8"), 1200, 128)), "13 9c 30 c0 96 6b c3 2b a5 5f db f2 12 53 0a c9");
assertStringEquals(hex(a1.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size", i2b(1200))), "59 d1 bb 78 9a 82 8b 1a a5 4e f9 c2 88 3f 69 ed");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size".getBytes("UTF-8"), 1200, 256)), "13 9c 30 c0 96 6b c3 2b a5 5f db f2 12 53 0a c9 c5 ec 59 f1 a4 52 f5 cc 9a d9 40 fe a0 59 8e d1");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size".getBytes("UTF-8"), 1200, 128)), "9c ca d6 d4 68 77 0c d5 1b 10 e6 a6 87 21 be 61");
assertStringEquals(hex(a1.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size", i2b(1200))), "cb 80 05 dc 5f 90 17 9a 7f 02 10 4c 00 18 75 1d");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size".getBytes("UTF-8"), 1200, 256)), "9c ca d6 d4 68 77 0c d5 1b 10 e6 a6 87 21 be 61 1a 8b 4d 28 26 01 db 3b 36 be 92 46 91 5e c8 2a");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, gclef.toCharArray(), "EXAMPLE.COMpianist".getBytes("UTF-8"), 50, 128)), "6b 9c f2 6d 45 45 5a 43 a5 b8 bb 27 6a 40 3b 39");
assertStringEquals(hex(a1.stringToKey(gclef.toCharArray(), "EXAMPLE.COMpianist", i2b(50))), "f1 49 c1 f2 e1 54 a7 34 52 d4 3e 7f e6 2a 56 e5");
assertStringEquals(hex((byte[])pbkdf2.invoke(null, gclef.toCharArray(), "EXAMPLE.COMpianist".getBytes("UTF-8"), 50, 256)), "6b 9c f2 6d 45 45 5a 43 a5 b8 bb 27 6a 40 3b 39 e7 fe 37 a0 c4 1e 02 c2 81 ff 30 69 e1 e9 4f 52");
if (EType.isSupported(EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96)) {
AesDkCrypto a2 = new AesDkCrypto(256);
assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1))), "fe 69 7b 52 bc 0d 3c e1 44 32 ba 03 6a 92 e6 5b bb 52 28 09 90 a2 fa 27 88 39 98 d7 2a f3 01 61");
assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(2))), "a2 e1 6d 16 b3 60 69 c1 35 d5 e9 d2 e2 5f 89 61 02 68 56 18 b9 59 14 b4 67 c6 76 22 22 58 24 ff");
assertStringEquals(hex(a2.stringToKey("password".toCharArray(), "ATHENA.MIT.EDUraeburn", i2b(1200))), "55 a6 ac 74 0a d1 7b 48 46 94 10 51 e1 e8 b0 a7 54 8d 93 b0 ab 30 a8 bc 3f f1 62 80 38 2b 8c 2a");
assertStringEquals(hex((byte[])s2k.invoke(a2, "password".toCharArray(), xeh("1234567878563412"), i2b(5))), "97 a4 e7 86 be 20 d8 1a 38 2d 5e bc 96 d5 90 9c ab cd ad c8 7c a4 8f 57 45 04 15 9f 16 c3 6e 31");
assertStringEquals(hex(a2.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase equals block size", i2b(1200))), "89 ad ee 36 08 db 8b c7 1f 1b fb fe 45 94 86 b0 56 18 b7 0c ba e2 20 92 53 4e 56 c5 53 ba 4b 34");
assertStringEquals(hex(a2.stringToKey("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX".toCharArray(), "pass phrase exceeds block size", i2b(1200))), "d7 8c 5c 9c b8 72 a8 c9 da d4 69 7f 0b b5 b2 d2 14 96 c8 2b eb 2c ae da 21 12 fc ee a0 57 40 1b");
assertStringEquals(hex(a2.stringToKey(gclef.toCharArray(), "EXAMPLE.COMpianist", i2b(50))), "4b 6d 98 39 f8 44 06 df 1f 09 cc 16 6d b4 b8 3c 57 18 48 b7 84 a3 d6 bd c3 46 58 9a 3e 39 3f 9e");
}
Cipher cipher = Cipher.getInstance("AES/CTS/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(
xeh("63 68 69 63 6b 65 6e 20 74 65 72 69 79 61 6b 69"), "AES"),
new IvParameterSpec(
xeh("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"), 0, 16));
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20"))),
"c6 35 35 68 f2 bf 8c b4 d8 a5 80 36 2d a7 ff 7f 97");
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20"))),
"fc 00 78 3e 0e fd b2 c1 d4 45 d4 c8 ef f7 ed 22 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5");
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43"))),
"39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84");
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c"))),
"97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 b3 ff fd 94 0c 16 a1 8c 1b 55 49 d2 f8 38 02 9e 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5");
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20"))),
"97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8");
assertStringEquals(hex(cipher.doFinal(
xeh("49 20 77 6f 75 6c 64 20 6c 69 6b 65 20 74 68 65 20 47 65 6e 65 72 61 6c 20 47 61 75 27 73 20 43 68 69 63 6b 65 6e 2c 20 70 6c 65 61 73 65 2c 20 61 6e 64 20 77 6f 6e 74 6f 6e 20 73 6f 75 70 2e"))),
"97 68 72 68 d6 ec cc c0 c0 7b 25 e2 5e cf e5 84 39 31 25 23 a7 86 62 d5 be 7f cb cc 98 eb f5 a8 48 07 ef e8 36 ee 89 a5 26 73 0d bc 2f 7b c8 40 9d ad 8b bb 96 c4 cd c0 3b c1 03 e1 a1 94 bb d8");
}
static byte[] i2b(int i) {
ByteBuffer bb = ByteBuffer.allocate(4);
byte[] b = new byte[4];
bb.putInt(i);
bb.flip();
bb.get(b);
return b;
}
static String hex(byte[] bs) {
StringBuffer sb = new StringBuffer(bs.length * 2);
for(byte b: bs) {
char c = (char)((b+256)%256);
if (c / 16 < 10)
sb.append((char)(c/16+'0'));
else
sb.append((char)(c/16-10+'a'));
if (c % 16 < 10)
sb.append((char)(c%16+'0'));
else
sb.append((char)(c%16-10+'a'));
}
return new String(sb);
}
static byte[] xeh(String in) {
in = in.replaceAll(" ", "");
int len = in.length()/2;
byte[] out = new byte[len];
for (int i=0; i<len; i++) {
out[i] = (byte)Integer.parseInt(in.substring(i*2, i*2+2), 16);
}
return out;
}
static void assertStringEquals(String a, String b) {
a = a.replaceAll(" ", "");
b = b.replaceAll(" ", "");
if (!a.equals(b)) {
throw new RuntimeException("Not equal: " + a + " AND " + b);
}
System.err.print(".");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册