下面列出了怎么用javax.security.auth.x500.X500Principal的API类实例代码及写法,或者点击链接到github查看源代码。
public static void main(String[] args) {
Subject subject = new Subject();
final Set principals = subject.getPrincipals();
principals.add(new X500Principal("CN=Alice"));
new Thread() {
{
start();
}
public void run() {
X500Principal p = new X500Principal("CN=Bob");
while (!finished) {
principals.add(p);
principals.remove(p);
}
}
};
for (int i = 0; i < 1000; i++) {
subject.getPrincipals(X500Principal.class);
}
finished = true;
}
private static X500Principal[] convertPrincipals(Principal[] principals) {
List<X500Principal> list = new ArrayList<>(principals.length);
for (int i = 0; i < principals.length; i++) {
Principal p = principals[i];
if (p instanceof X500Principal) {
list.add((X500Principal)p);
} else {
try {
list.add(new X500Principal(p.getName()));
} catch (IllegalArgumentException e) {
// ignore
}
}
}
return list.toArray(new X500Principal[list.size()]);
}
/**
* Extract the issuer X500Principal from an X509CRL. Parses the encoded
* form of the CRL to preserve the principal's ASN.1 encoding.
*
* Called by java.security.cert.X509CRL.getIssuerX500Principal().
*/
public static X500Principal getIssuerX500Principal(X509CRL crl) {
try {
byte[] encoded = crl.getEncoded();
DerInputStream derIn = new DerInputStream(encoded);
DerValue tbsCert = derIn.getSequence(3)[0];
DerInputStream tbsIn = tbsCert.data;
DerValue tmp;
// skip version number if present
byte nextByte = (byte)tbsIn.peekByte();
if (nextByte == DerValue.tag_Integer) {
tmp = tbsIn.getDerValue();
}
tmp = tbsIn.getDerValue(); // skip signature
tmp = tbsIn.getDerValue(); // issuer
byte[] principalBytes = tmp.toByteArray();
return new X500Principal(principalBytes);
} catch (Exception e) {
throw new RuntimeException("Could not parse issuer", e);
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
private void generateKeysForAPILessThanM(String keyAlias) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, CertificateException, UnrecoverableEntryException, NoSuchPaddingException, KeyStoreException, InvalidKeyException, IOException {
// Generate a key pair for encryption
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 30);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(mContext)
.setAlias(keyAlias)
.setSubject(new X500Principal("CN=" + keyAlias))
.setSerialNumber(BigInteger.TEN)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM_NAME, ANDROID_KEY_STORE_NAME);
kpg.initialize(spec);
kpg.generateKeyPair();
saveEncryptedKey();
}
/**
* Populate the trustedSubjects Map using the DN and public keys from
* the list of trusted certificates
*
* @return Map containing each subject DN and one or more public keys
* tied to those DNs.
*/
private Map<X500Principal, List<PublicKey>> setTrustedSubjects() {
Map<X500Principal, List<PublicKey>> subjectMap = new HashMap<>();
for (X509Certificate cert : trustedCerts) {
X500Principal dn = cert.getSubjectX500Principal();
List<PublicKey> keys;
if (subjectMap.containsKey(dn)) {
keys = subjectMap.get(dn);
} else {
keys = new ArrayList<PublicKey>();
subjectMap.put(dn, keys);
}
keys.add(cert.getPublicKey());
}
return subjectMap;
}
public void performMapping(Map<String,Object> contextMap, Principal principal)
{
if(principal instanceof X500Principal == false)
return;
if(contextMap == null)
throw PicketBoxMessages.MESSAGES.invalidNullArgument("contextMap");
X509Certificate[] certs = (X509Certificate[]) contextMap.get("X509");
if(certs != null)
{
SubjectCNMapping sdn = new SubjectCNMapping();
principal = sdn.toPrinicipal(certs);
PicketBoxLogger.LOGGER.traceMappedX500Principal(principal);
}
result.setMappedObject(principal);
}
/**
* Extract the subject or issuer X500Principal from an X509Certificate.
* Parses the encoded form of the cert to preserve the principal's
* ASN.1 encoding.
*/
private static X500Principal getX500Principal(X509Certificate cert,
boolean getIssuer) throws Exception {
byte[] encoded = cert.getEncoded();
DerInputStream derIn = new DerInputStream(encoded);
DerValue tbsCert = derIn.getSequence(3)[0];
DerInputStream tbsIn = tbsCert.data;
DerValue tmp;
tmp = tbsIn.getDerValue();
// skip version number if present
if (tmp.isContextSpecific((byte)0)) {
tmp = tbsIn.getDerValue();
}
// tmp always contains serial number now
tmp = tbsIn.getDerValue(); // skip signature
tmp = tbsIn.getDerValue(); // issuer
if (getIssuer == false) {
tmp = tbsIn.getDerValue(); // skip validity
tmp = tbsIn.getDerValue(); // subject
}
byte[] principalBytes = tmp.toByteArray();
return new X500Principal(principalBytes);
}
static TrustManager[] fromPemCertificatesFile(List<Path> trustedCertificates)
throws GeneralSecurityException, IOException {
final KeyStore trustStore = KeyStore.getInstance(KEYSTORE_TYPE);
trustStore.load(null, null);
List<X509Certificate> certificates = new ArrayList<>();
for (Path path : trustedCertificates) {
certificates.addAll(getCertificates(path));
}
for (X509Certificate certificate : certificates) {
X500Principal principal = certificate.getSubjectX500Principal();
trustStore.setCertificateEntry(principal.getName("RFC2253"), certificate);
}
final TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
return trustManagerFactory.getTrustManagers();
}
/**
* Parse an argument of the form passed to setIssuerNames,
* returning a Collection of issuerX500Principals.
* Throw an IOException if the argument is malformed.
*
* @param names a {@code Collection} of names. Each entry is a
* String or a byte array (the name, in string or ASN.1
* DER encoded form, respectively). <Code>Null</Code> is
* not an acceptable value.
* @return a HashSet of issuerX500Principals
* @throws IOException if a parsing error occurs
*/
private static HashSet<X500Principal> parseIssuerNames(Collection<Object> names)
throws IOException {
HashSet<X500Principal> x500Principals = new HashSet<X500Principal>();
for (Iterator<Object> t = names.iterator(); t.hasNext(); ) {
Object nameObject = t.next();
if (nameObject instanceof String) {
x500Principals.add(new X500Name((String)nameObject).asX500Principal());
} else {
try {
x500Principals.add(new X500Principal((byte[])nameObject));
} catch (IllegalArgumentException e) {
throw (IOException)new IOException("Invalid name").initCause(e);
}
}
}
return x500Principals;
}
/**
* Extract the subject or issuer X500Principal from an X509Certificate.
* Parses the encoded form of the cert to preserve the principal's
* ASN.1 encoding.
*/
private static X500Principal getX500Principal(X509Certificate cert,
boolean getIssuer) throws Exception {
byte[] encoded = cert.getEncoded();
DerInputStream derIn = new DerInputStream(encoded);
DerValue tbsCert = derIn.getSequence(3)[0];
DerInputStream tbsIn = tbsCert.data;
DerValue tmp;
tmp = tbsIn.getDerValue();
// skip version number if present
if (tmp.isContextSpecific((byte)0)) {
tmp = tbsIn.getDerValue();
}
// tmp always contains serial number now
tmp = tbsIn.getDerValue(); // skip signature
tmp = tbsIn.getDerValue(); // issuer
if (getIssuer == false) {
tmp = tbsIn.getDerValue(); // skip validity
tmp = tbsIn.getDerValue(); // subject
}
byte[] principalBytes = tmp.toByteArray();
return new X500Principal(principalBytes);
}
public static void main(String[] args) throws Exception {
String dn="CN=\\#user";
X500Principal xp = new X500Principal(dn);
System.out.println("RFC2253 DN is " +
xp.getName(X500Principal.RFC2253));
System.out.println("CANONICAL DN is is " +
xp.getName(X500Principal.CANONICAL));
String dn1 = xp.getName(X500Principal.CANONICAL);
if (!(dn1.substring(3,5).equals("\\#")))
throw new Exception("Leading # not escaped");
X500Principal xp1 = new X500Principal(dn1);
System.out.println("CANONICAL DN is " +
xp1.getName(X500Principal.CANONICAL));
}
private static X500Principal[] convertPrincipals(Principal[] principals) {
List<X500Principal> list = new ArrayList<>(principals.length);
for (int i = 0; i < principals.length; i++) {
Principal p = principals[i];
if (p instanceof X500Principal) {
list.add((X500Principal)p);
} else {
try {
list.add(new X500Principal(p.getName()));
} catch (IllegalArgumentException e) {
// ignore
}
}
}
return list.toArray(new X500Principal[list.size()]);
}
private X509CertificateBuilder(X500Principal issuer,
X500Principal subject,
Instant notBefore,
Instant notAfter,
PublicKey certPublicKey,
PrivateKey caPrivateKey,
SignatureAlgorithm signingAlgorithm,
BigInteger serialNumber) {
this.issuer = issuer;
this.subject = subject;
this.notBefore = notBefore;
this.notAfter = notAfter;
this.certPublicKey = certPublicKey;
this.caPrivateKey = caPrivateKey;
this.signingAlgorithm = signingAlgorithm;
this.serialNumber = serialNumber;
}
/**
* @param issuers The list of acceptable CA issuer subject names or null if it does not matter which issuers are used
* @return True if certificate matches issuer and key type
*/
protected boolean matches(final Certificate c, final String[] keyTypes, final Principal[] issuers) {
if(!(c instanceof X509Certificate)) {
log.warn(String.format("Certificate %s is not of type X509", c));
return false;
}
if(!Arrays.asList(keyTypes).contains(c.getPublicKey().getAlgorithm())) {
log.warn(String.format("Key type %s does not match any of %s", c.getPublicKey().getAlgorithm(),
Arrays.toString(keyTypes)));
return false;
}
if(null == issuers || Arrays.asList(issuers).isEmpty()) {
// null if it does not matter which issuers are used
return true;
}
final X500Principal issuer = ((X509Certificate) c).getIssuerX500Principal();
if(!Arrays.asList(issuers).contains(issuer)) {
log.warn(String.format("Issuer %s does not match", issuer));
return false;
}
return true;
}
/**
* Returns a copy of this object.
*
* @return the copy
*/
public Object clone() {
try {
X509CRLSelector copy = (X509CRLSelector)super.clone();
if (issuerNames != null) {
copy.issuerNames =
new HashSet<Object>(issuerNames);
copy.issuerX500Principals =
new HashSet<X500Principal>(issuerX500Principals);
}
return copy;
} catch (CloneNotSupportedException e) {
/* Cannot happen */
throw new InternalError(e.toString(), e);
}
}
/**
* Fetch CRLs from certStores.
*
* @throws CertStoreException if there is an error retrieving the CRLs from
* one of the CertStores and no other CRLs are retrieved from
* the other CertStores. If more than one CertStore throws an
* exception then the one from the last CertStore is thrown.
*/
private static Collection<X509CRL> getCRLs(X500Name name,
X500Principal certIssuer,
List<CertStore> certStores)
throws CertStoreException
{
if (debug != null) {
debug.println("Trying to fetch CRL from DP " + name);
}
X509CRLSelector xcs = new X509CRLSelector();
xcs.addIssuer(name.asX500Principal());
xcs.addIssuer(certIssuer);
Collection<X509CRL> crls = new ArrayList<>();
CertStoreException savedCSE = null;
for (CertStore store : certStores) {
try {
for (CRL crl : store.getCRLs(xcs)) {
crls.add((X509CRL)crl);
}
} catch (CertStoreException cse) {
if (debug != null) {
debug.println("Exception while retrieving " +
"CRLs: " + cse);
cse.printStackTrace();
}
savedCSE = new PKIX.CertStoreTypeException(store.getType(),cse);
}
}
// only throw CertStoreException if no CRLs are retrieved
if (crls.isEmpty() && savedCSE != null) {
throw savedCSE;
} else {
return crls;
}
}
@Override
public X509CRLSelector wrap(X509CRLSelector selector,
Collection<X500Principal> certIssuers,
String ldapDN)
throws IOException
{
throw new UnsupportedOperationException();
}
/**
* Inits X500Principal with a string, there are multiple AVAs and Oid which does not fall into any keyword
* Gets encoding
* Inits other X500Principal with the encoding
* gets string in RFC2253 format
* compares with expected value paying attention on sorting order of AVAs
*/
public void testGetName_EncodingWithWrongOidButGoodName_MultAVA_RFC2253()
throws Exception {
String dn = "OID.2.16.4.3=B + CN=A";
X500Principal principal = new X500Principal(dn);
byte[] enc = principal.getEncoded();
X500Principal principal2 = new X500Principal(enc);
String s = principal2.getName(X500Principal.RFC2253);
assertTrue("2.16.4.3=#130142+CN=A".equals(s) ||
"CN=A+2.16.4.3=#130142".equals(s));
}
public static void main(String args[]) {
Subject subject = new Subject();
subject.getPrincipals().add(new X500Principal("CN=Duke"));
Subject anotherSubject = new Subject();
anotherSubject.getPrincipals().add(new X500Principal("CN=Java"));
ReadFromFileAction readFromFile
= new ReadFromFileAction(NestedActions.file, anotherSubject);
WriteToFileAction writeToFile
= new WriteToFileAction(NestedActions.file, readFromFile);
Subject.doAs(subject, writeToFile);
}
public void testGetIssuerX500Principal() {
// return valid encoding
MyX509Certificate cert = new MyX509Certificate() {
private static final long serialVersionUID = 638659908323741165L;
public byte[] getEncoded() {
return TestUtils.getX509Certificate_v1();
}
};
assertEquals(new X500Principal("CN=Z"), cert.getIssuerX500Principal());
}
public DistinguishedNameParser(X500Principal principal) {
// RFC2253 is used to ensure we get attributes in the reverse
// order of the underlying ASN.1 encoding, so that the most
// significant values of repeated attributes occur first.
this.dn = principal.getName(X500Principal.RFC2253);
this.length = this.dn.length();
}
private static PKCS10CertificationRequest generateCsrWithName(KeyPair identity, String name, List<String> sanList) throws Exception {
X500Principal principal = new X500Principal(name);
PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(principal, identity.getPublic());
if (!CollectionUtils.isEmpty(sanList)) {
p10Builder = addSubjectAlternativeNames(p10Builder, sanList);
}
JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
ContentSigner signer = csBuilder.build(identity.getPrivate());
return p10Builder.build(signer);
}
public static X509Certificate generateSignedCertificate(X509Certificate caCertificate, PrivateKey caPrivateKey, PublicKey publicKey, String CN)
throws NoSuchAlgorithmException, OperatorCreationException, CertificateException,
KeyStoreException, UnrecoverableKeyException, IOException,
InvalidKeyException, NoSuchPaddingException, InvalidParameterSpecException,
InvalidKeySpecException, InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException {
X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
builder.addRDN(BCStyle.CN, CN);
// We want this root certificate to be valid for one year
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 1);
ContentSigner sigGen = new JcaContentSignerBuilder("SHA1WithRSAEncryption").setProvider(BC).build(caPrivateKey);
X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
caCertificate,
new BigInteger(80, new Random()),
new Date(System.currentTimeMillis() - 50000),
calendar.getTime(),
new X500Principal(builder.build().getEncoded()),
publicKey);
// Those are the extensions needed for the certificate to be a leaf certificate that authenticates a SSL server
certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.15"), true, new X509KeyUsage(X509KeyUsage.keyEncipherment));
certGen.addExtension(new ASN1ObjectIdentifier("2.5.29.37"), true, new DERSequence(KeyPurposeId.id_kp_serverAuth));
X509CertificateHolder certificateHolder = certGen.build(sigGen);
X509Certificate certificate = new JcaX509CertificateConverter().setProvider(BC).getCertificate(certificateHolder);
return certificate;
}
@Override
public X509CRLSelector wrap(X509CRLSelector selector,
Collection<X500Principal> certIssuers,
String ldapDN)
throws IOException
{
return new LDAPCertStore.LDAPCRLSelector(selector, certIssuers, ldapDN);
}
X500Principal getX500Principal() throws IOException {
try {
return new X500Principal(name);
} catch (IllegalArgumentException e) {
throw (SSLProtocolException)new SSLProtocolException(
e.getMessage()).initCause(e);
}
}
/**
* Inits X500Principal with the string with special characters - \\'space''space'B
* gets Name in RFC1779 format
* compares with expected value of name - \'space''space'B
*/
public void testNameSpaces_RFC2253_02() throws Exception {
String dn = "CN=\\ B";
X500Principal principal = new X500Principal(dn);
String s = principal.getName(X500Principal.RFC2253);
assertEquals("CN=\\ \\ B", s);
}
@Test
public void can_deserialize_serialized_pem_csr() {
X500Principal subject = new X500Principal("CN=subject");
KeyPair keypair = KeyUtils.generateKeypair(KeyAlgorithm.EC, 256);
Pkcs10Csr csr = Pkcs10CsrBuilder.fromKeypair(subject, keypair, SignatureAlgorithm.SHA512_WITH_ECDSA).build();
String pem = Pkcs10CsrUtils.toPem(csr);
Pkcs10Csr deserializedCsr = Pkcs10CsrUtils.fromPem(pem);
assertThat(pem, containsString("BEGIN CERTIFICATE REQUEST"));
assertThat(pem, containsString("END CERTIFICATE REQUEST"));
assertEquals(subject, deserializedCsr.getSubject());
}
/**
* Creates an LDAPCRLSelector.
*
* @param selector the X509CRLSelector to wrap
* @param certIssuers the issuer DNs of the CRLs that you want
* to retrieve via LDAP
* @param ldapDN the LDAP DN where the CRL is stored
*/
LDAPCRLSelector(X509CRLSelector selector,
Collection<X500Principal> certIssuers, String ldapDN)
throws IOException {
this.selector = selector == null ? new X509CRLSelector() : selector;
this.certIssuers = certIssuers;
issuerNames = new HashSet<>();
issuerNames.add(ldapDN);
issuers = new HashSet<>();
issuers.add(new X500Name(ldapDN).asX500Principal());
}
/**
* Inits X500Principal with the string with special characters - \"B
* gets Name in RFC2253 format
* compares with expected value of name - "\B"
*/
public void testNameSpecialChars_RFC2253() throws Exception {
String dn = "CN=A,CN=\\\"B";
X500Principal principal = new X500Principal(dn);
String s = principal.getName(X500Principal.RFC2253);
assertEquals("CN=A,CN=\\\"B", s);
}
@Override
public X509CertSelector wrap(X509CertSelector selector,
X500Principal certSubject,
String ldapDN)
throws IOException
{
return new LDAPCertStore.LDAPCertSelector(selector, certSubject, ldapDN);
}