我有一个如下所示的XML文件:
<Envelope>
<Body>
<user1>
<userId>userName</userId>
<password>password</password>
<creditCard>
<creditCardNumber>12345678901234</creditCardNumber>
<cvv>123</cvv>
</creditCard>
</user1>
<user2>
<userId>userName</userId>
<password>password</password>
<creditCard>
<creditCardNumber>12345678901234</creditCardNumber>
<cvv>123</cvv>
</creditCard>
</user2>
</Body>
</Envelope>
我有一个Java代码,用于将xml事务登录到某些服务器上,以备将来参考。此Java代码具有一些方法,可以在登录之前掩盖标签的某些字符或整个值,因为不会透露信用卡详细信息。
方法如下:
public static String mask( String input, String[] tags, String maskPattern, String namespacePattern)
throws Throwable
{
StringBuffer sb = new StringBuffer( input );
encodedXML = false;
if (sb.indexOf( ">" ) > 0) {
// XML is encoded
gt = ">";
lt = "<";
encodedXML = true;
// modify patterns for encoded xml
maskPattern = "(>)" + alphaNumericStuff + "+(<)/";
if (sb.indexOf( """ ) >= 0) {
// There is a mix of double quotes and " in this xml
namespacePattern = mixedEncodingAlphaNumericStuff + "*";
}
}
for (int i = 0; i < tags.length; i++) {
// do a quick check to see if the tag is in the string to reduce excessive string creation
if (sb.indexOf( tags[i] ) < 0) {
continue;
} else {
sb = maskElementValue( sb, tags[i],maskPattern, namespacePattern );
}
}
return sb.toString();
}
private static StringBuffer maskElementValue( StringBuffer sb, String tag, String maskPattern,String namespacePattern)
{
// Pattern p = Pattern.compile( tag + maskPattern ); doesn't take namespace into account
Pattern p = Pattern.compile( tag + namespacePattern + maskPattern );
Matcher m = p.matcher( sb.toString() );
StringBuffer tempSB = new StringBuffer();
String namespaceStr = "";
while (m.find()) {
namespaceStr = m.group().substring( tag.length(), m.group().indexOf( gt ) );
// Added full masking for username and password including last 4 characters
if (tag.equalsIgnoreCase( "username" ) || tag.equalsIgnoreCase( "password" )) {
m.appendReplacement( tempSB, tag + namespaceStr + gt + xOut( new StringBuffer( m.group().substring( tag.length() + namespaceStr.length() + gt.length() ) ), true ) );
} else {
m.appendReplacement( tempSB, tag + namespaceStr + gt + xOut( new StringBuffer( m.group().substring( tag.length() + namespaceStr.length() + gt.length() ) ), false ) );
}
}
m.appendTail( tempSB );
return tempSB;
}
private static String xOut( StringBuffer sb, boolean maskAll )
{
int dataSize = sb.toString().trim().length() - 1 - lt.length();
if (!maskAll && dataSize > 4) {
if (sb.indexOf( "<" ) > 0 || sb.indexOf( "<" ) > 0) {
StringBuffer tempmaskSB = new StringBuffer( sb.substring( 0, sb.indexOf( "<" ) ) );
dataSize = tempmaskSB.length();
}
// Don't mask last 4 digit
for (int i = 0; i < dataSize - 4; i++) {
sb.setCharAt( i, 'X' );
}
} else {
if (sb.indexOf( "<" ) > 0 || sb.indexOf( "<" ) > 0) {
StringBuffer tempmaskSB = new StringBuffer( sb.substring( 0, sb.indexOf( "<" ) ) );
dataSize = tempmaskSB.length();
}
// Mask all
for (int i = 0; i < dataSize; i++) {
sb.setCharAt( i, 'X' );
}
}
return sb.toString();
}
我将xml作为字符串传递给方法和要屏蔽的标记数组。如果是用户名和密码,则应将其完全屏蔽,并应屏蔽数组中的其他标记(除最后4个字符外)。
现在的问题是,某些事务没有发生屏蔽。当我们完成了负载测试后,在18000个事务中有12个未屏蔽受保护的数据。
在某些情况下,同一事务中的user1详细信息会被屏蔽,但不会屏蔽user2详细信息。
有人可以帮助我理解为什么会这样吗?有人遇到过这样的问题吗?
提前致谢。
最佳答案
不知道这是否有帮助。但是我会用jsoup做掩饰部分
例:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
public class Mask {
static String xml = "<Envelope>\n" +
"<Body>\n" +
" <user1>\n" +
" <userId>userName</userId>\n" +
" <password>password</password>\n" +
" <creditCard>\n" +
" <creditCardNumber>12345678901234</creditCardNumber>\n" +
" <cvv>123</cvv>\n" +
" </creditCard>\n" +
" </user1>\n" +
" <user2>\n" +
" <userId>userName</userId>\n" +
" <password>password</password>\n" +
" <creditCard>\n" +
" <creditCardNumber>12345678901234</creditCardNumber>\n" +
" <cvv>123</cvv>\n" +
" </creditCard>\n" +
" </user2>\n" +
"</Body>\n" +
"</Envelope>";
public static void main (String[]args){
Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
Elements toMaskCompletely = doc.select("userId,password");
Elements toMaskPartially = doc.select("creditCardNumber");
for(Element ele : toMaskCompletely){
ele.text("XXXXX");
}
for(Element ele : toMaskPartially){
ele.text("XXXXXXXX"+ele.text().substring(ele.text().length()-4));
}
System.out.println(doc.toString());
}
}
关于java - 在Java中屏蔽XML标签值的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39635769/