CN-ді DN сертификатынан талдау

Мәселен, бұл эстетика мәселесі екенін бастайық. Мен өз мәселемді шешіп алдым, оны жасаудың жақсы әдістерін сұраймын.

Міне, менде DN сертификаты бар.

CN = Jimmy Blooptoop, OU = Someplace, OU = Қызметкерлер, DC = Bloopsoft-Inc

Now, I want to grab the CN out of that. In java, there isn't native support to grab anything but the full DN from the X509 certificate without using some 3rd party library like bouncy castle - which I can't use. So I've got to parse it out, which isn't much of problem. The only thing that makes it slightly tricky is the fact that the CN isn't always going to be formatted as . More often than not, it's actually going to be , . So, in the example above, the CN could be Jimmy Blooptoop or Blooptoop, Jimmy J (short for the Joop of course).

Туралы әңгімелер туралы әңгімелеп, оқып шыққаннан кейін мен жақсы жұмыс істейтін төмендегілерді жаздым:

Matcher m = Pattern.compile("CN=[A-Za-z]*[, ]*[ A-Za-z]*").matcher(dn);
if (m.find())
  cn = m.group();

Мен жай ғана қызықпаймын, әлдеқайда аз көрінетін сөздер бар ма? Мен регрессия туралы ғана әңгімелеуді оқығаннан кейін жұмыс істегеніме сенімдімін.

21

9 жауаптар

javax.naming.ldap.LdapName туралы не айтасыз?

String dn = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc";
LdapName ln = new LdapName(dn);

for(Rdn rdn : ln.getRdns()) {
    if(rdn.getType().equalsIgnoreCase("CN")) {
        System.err.println("CN is: " + rdn.getValue());
        break;
    }
}

Бұл ең әдемі интерфейс емес, өйткені LdapName # getByType (String) сияқты жоғалып кететін нәрсе бар, бірақ ол сізді DN-тің қандай ерекше ерекшеліктері туралы ойланудың қиындықтарынан құтқарады.

51
қосылды
@gregschlom: Сен соншалықты дұрыссың. Мен ескі мектеп циклына неге барғанымды білмеймін.
қосылды автор musiKk, көзі
Бұл тәсіл көптеген құнды RDN-ді қамтитын DN-мен шектеулерге ие, мысалы: OU = Sales + CN = J. Смит, O = Widget Inc., C = US . Бұл жағдайда сіз Rdn.toAttributes (). GetAll() пайдалана аласыз және қайталанатын санаудың үстінен қайталаңыз.
қосылды автор Jaime Hablutzel, көзі
қосылды автор likejiujitsu, көзі
Жақсы шешім: for (Rdn rdn: ln.getRdns ()) {...}
қосылды автор gregschlom, көзі
BouncyCastle API интерфейсін пайдаланып, тұрақты өрнекпен салыстырғанда, әлдеқайда қатаң шешім - басқа таңдау, Java-дегі x509certificate-дан cn қалай шығаруға болады
қосылды автор jmd, көзі

'Crappy' өрнегін пайдаланудан аулақ бола аласыз. Егер сізде DN бар болса, Жолды бөліп, содан кейін CN-ды табуға болады. Мысалға:

String dn = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc";
String[] split = dn.split(","); 
for (String x : split) {
    if (x.contains("CN=")) {
        System.out.println(x.trim());
    }
}
5
қосылды
@JesseWebb: String # split() сондай-ақ Regex жасайды.
қосылды автор musiKk, көзі
L = Scottsdale, ST = Аризона, C = US - G2, O = «GoDaddy.com, Inc.», CN = Go Daddy Root Certificate Authority -
қосылды автор Andrew Alcock, көзі
Regex жұмыс істегенімен, олар әдетте қымбат тұрады. Осындай қарапайым жол форматы үшін, үтірмен бөлінген, жолды бөлу жақсы болады. Өкінішке орай, ОП құндылықтар кейде үтірлерді қамтуы мүмкін деп мәлімдеді, бұл шешім бұл шешімді жасамайды.
қосылды автор Jesse Webb, көзі
@musiKk - Сізге рахмет, бұл туралы білмеймін. Менің ойымша, шешім бірдей қымбатқа түседі.
қосылды автор Jesse Webb, көзі
Сонымен қатар, CN = Development Cyanogen Application, OU = Release Management, O = Cyanogen \, Inc., L = Сиэтл, ST = Вашингтон, C = US
қосылды автор tophyr, көзі

Егер сіз Spring Framework бағдарламасын пайдалансаңыз, сіз DistinguishedName келесідей:

String path = "CN=Jimmy Blooptoop,OU=Someplace,OU=Employees,DC=Bloopsoft-Inc";
DistinguishedName dn = new DistinguishedName(path);

String cn = dn.getValue("cn");//Jimmy Blooptoop
4
қосылды
DistinguishedName енді javax.naming.ldap.LdapName пайдаланудың пайдасына қолданылмайды. Бірақ, атыңызды одан LdapUtils.getStringValue (ldapName, «cn») арқылы шығарып алу үшін,
қосылды автор jbx, көзі

CN -ді төмендегідей етіп алу үшін Spring Frameworks LdapUtils қолдануға болады:

String cn = LdapUtils.getStringValue(new LdapName(group),"cn");

ЖӘНЕ

Without using Spring Framework like below :

String cn = (String)new LdapName(group).getRdns().stream().filter(rdn -> rdn.getType().equalsIgnoreCase("CN")).findFirst().get().getValue();
2
қосылды

Егер мен оны дұрыс түсінсем, сол нәтижені жасау керек, тек біршама оқылатын көрінеді. \ w кез келген сөз таңбасына сәйкес келеді.

"CN=[\\w]*[., ]+[\\w ]*"

Егер сізге икемді нәрсе келсе, мұны істей аласыз:

Matcher m = Pattern.compile("(CN=.*?),[A-Z]{2}=").matcher(dn);
if (m.find())
  cn = m.group(1);

Бұл «CN =» және «XX =» арасындағы кез келген нәрсеге сәйкес келеді, мұнда XX - екі бас әріп. group (1) бірінші топты қайтарады (жақшаның ішіндегі матч).

Regexp-дің көрінуі қиын емес!

1
қосылды
C = US => «GoDaddy.com, Inc.», L = Scottsdale, ST = Arizona, C = US
қосылды автор Andrew Alcock, көзі

Жоғарыдағы ұсынылған әдеттегі сөздерді қолдануға болмайды. Бұл қалыпты өрнектермен байланысты мәселе сіз бұрын RFC 4514 -ні қадағаламайсыз және бұдан бұрын ашылмайсыз қашып кеткен символдар мен айырымдық атауды ықтимал жоғалтып немесе дұрыс түсінбеуі мүмкін. musiKk ұсынған орнына LdapName класын пайдаланыңыз.

1
қосылды

Мен ДН-ны осылай талдаймын. Барлық төлсипаттарды сипаттар ретінде аласыз:

Principal principal = cert.getSubjectDN();
Properties prop = new Properties();
prop.load(new StringReader(principal.getName().replaceAll(",", "\n")));
prop.list(System.out);
String CN= props.get("CN");

Ол, ou немесе dc сияқты қайталанатын элементтер үшін жұмыс істемейді.

1
қосылды
Басқа қарапайым regex/split «solutions» сияқты, бұл CN = Go Daddy Root Certificate Authority - G2, O = «GoDaddy.com, Inc.», L = Scottsdale, ST сияқты секциялардағы үтірлерге сәтсіздікке ұшырайды. = Аризона, C = US
қосылды автор Emil Lundberg, көзі

Ұқсас, бұл жұмыс істейді

CertificateFactory fact = CertificateFactory.getInstance("X.509");
FileInputStream is = new FileInputStream ("cert.pem");
X509Certificate cert = (X509Certificate) fact.generateCertificate(is);
String cn = ((X500Name)cert.getSubjectDN()).getCommonName()
0
қосылды

Regex өрнектерін пайдалану өте қымбат. Осындай қарапайым тапсырма үшін ол өлтіруге болады. Оның орнына сіз қарапайым Жолды бөлуді пайдалана аласыз:

String dn = ((X509Certificate) certificate).getIssuerDN().getName();
String CN = getValByAttributeTypeFromIssuerDN(dn,"CN=");

private String getValByAttributeTypeFromIssuerDN(String dn, String attributeType)
{
    String[] dnSplits = dn.split(","); 
    for (String dnSplit : dnSplits) 
    {
        if (dnSplit.contains(attributeType)) 
        {
            String[] cnSplits = dnSplit.trim().split("=");
            if(cnSplits[1]!= null)
            {
                return cnSplits[1].trim();
            }
        }
    }
    return "";
}
0
қосылды
Басқа қарапайым regex/split «solutions» сияқты, бұл CN = Go Daddy Root Certificate Authority - G2, O = «GoDaddy.com, Inc.», L = Scottsdale, ST сияқты секциялардағы үтірлерге сәтсіздікке ұшырайды. = Аризона, C = US
қосылды автор Emil Lundberg, көзі