Sending certificate with future timestamp - java

Suppose two people run the same code and the first one creates a certificate with createDate and expireDate and a file is valid if
createDate < currentTimeOfTheUserComputer < expireDate .
Now if the first person sends this certificate(suppose for him it is valid) to someone else who is 8 hours behind around the world ,for the second person it will be invalid.In such a scenario how is this problem resolved or is there a policy how it should be if we want the second person to be able to use it without waiting 8 hours?

RFC 5280, which handles X.509 certificates specifies two methods to encode validity times in certificates:
UTCTime
GeneralizedTime
Both rely on the GMT zone as reference. If both implementations use the correct time zone for generation and checking, your scenario should not present a problem.
See RFC 5280 on validity

EDIT: Sorry, I didn't realize that Date always uses UTC Time. So any time you want to get the date, you access it like this:
import java.util.Date;
public class CurrentDateTime {
public static String getCurrDateTime() {
Date date = new Date();
return date;
}
}
public class DateCertificate {
public static void createCertificate() {
Date createDate = CurrentDateTime.getCurrDateTime();
/* Save createDate to file or something */
}
public static boolean certificateValid() {
Date currentDate = CurrentDateTime.getCurrDateTime();
/* Get createDate and expireDate from file or something */
return currentDate.after(createDate) && currentDate.before(expireDate);
}
}
You can use getCurrDateTime() and some other Date methods to get the createDate and expireDate and save them to a file or however you want to store them, then use the certificateValid() method to check if the currentDate is between the two.
Thanks Jim for pointing out my mistake.
Note: This could be easily spoofed/tricked because it is dependent on the time reading from the client machine that is given to the JVM. So do not use this for free trial validation or the like.

Related

convert xmlGregorianCalendar to Date and reverse

i all, i have a spring boot application. what i want in specific is to convert a class (that have nestet object field) in his corrispective entity. example:
public class example{
String string;
ObjectExample object;
}
public class ObjectExample{
String oneString;
XMLGregorianCalendar date;
}
this 2 object are also marked in another package as entities, but ovviusly in the ObjectExampleEntity i have Date date instead XMLGregorianCalendar, like this with the example
#Entity
public class example{
String string;
ObjectExample object;
}
#Entity
public class ObjectExample{
String oneString;
Date date;
}
because i have a big model and big entity (this above is only an example) with a lot of nested classes , i use dozer to convert from the model to the class.
consider for example that the repository jpa is only created for the father example class.
i want to know how i can with dozer convert from Date (entity) to XMLGregorianCalendar (model) and reverse. the model and the entity,i repeat are equal. the only difference is the type of the date. thanks
I am assuming:
Since your variable is named date it contains a calendar date (without time of day).
You are tied to XMLGregorianCalendar because of a WSDL outside your control, but you can change type on the entity side.
Based on these assumptions I recommend LocalDate on the entity side. It’s part of java.time, the modern Java date and time API, and represents exactly a date without time of day. The Date class that you used is poorly designed, long outdated and not recommended. Also despite the name a Date never represented a date, but a point in time.
There are more options. I am presenting three.
Option 1: transfer individual fields
From XMLGregorianCalendar to LocalDate:
DatatypeFactory xmlFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar wsDate = xmlFactory
.newXMLGregorianCalendarDate(2019, DatatypeConstants.MARCH, 30,
DatatypeConstants.FIELD_UNDEFINED);
// Validate
if ((wsDate.getHour() != 0 && wsDate.getHour() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMinute() != 0 && wsDate.getMinute() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getSecond() != 0 && wsDate.getSecond() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMillisecond() != 0 && wsDate.getMillisecond() != DatatypeConstants.FIELD_UNDEFINED)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (wsDate.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Convert
LocalDate entityDate = LocalDate.of(wsDate.getYear(), wsDate.getMonth(), wsDate.getDay());
System.out.println(entityDate);
The output is in this case:
2019-03-30
From LocalDate to XMLGregorianCalendar:
LocalDate entityDate = LocalDate.of(2019, Month.MARCH, 31);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendarDate(
entityDate.getYear(),
entityDate.getMonthValue(),
entityDate.getDayOfMonth(),
DatatypeConstants.FIELD_UNDEFINED);
System.out.println(wsDate);
2019-03-31
Advantage of this way: It’s pretty straightforward. Disadvantage: You and your reader need to take care that the fields are mentioned in the right order.
Option 2: convert via strings
// Validate as before
// Convert
LocalDate entityDate = LocalDate.parse(wsDate.toXMLFormat());
Result is as before.
XMLGregorianCalendar wsDate
= xmlFactory.newXMLGregorianCalendar(entityDate.toString());
Advantage: it’s brief, and there’s no surprise that the results are correct. Disadvantage: To me it feels like a waste to format into a string only to parse it back.
Option 3: convert via GregorianCalendar and ZonedDateTime
ZonedDateTime zdt = wsDate.toGregorianCalendar().toZonedDateTime();
// Validate
if (! zdt.toLocalTime().equals(LocalTime.MIN)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (! zdt.getZone().equals(ZoneId.systemDefault())) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Finish conversion
LocalDate entityDate = zdt.toLocalDate();
And the other way:
// It doesn’t matter which time zone we pick
// since we are discarding it after conversion anyway
ZonedDateTime zdt = entityDate.atStartOfDay(ZoneOffset.UTC);
GregorianCalendar gCal = GregorianCalendar.from(zdt);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendar(gCal);
wsDate.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
wsDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
The validation I present here is a bit simpler but also not quite so strict. If you want strict validation, you can just use the validation from before.
Advantages: I think it’s the official way; at least it uses the conversion methods offered. What I like is that the conversion itself is direct and brief. Disadvantage: When converting to XMLGregorianCalendar we need to set the unused fields to undefined manually, which makes it wordy.
Conclusion
I have presented three options each with their pros and cons. You may also mix, of course, but using a similar conversion both ways is probably less confusing in the end.

Will creation of java.time.LocalTime also trigger creation of sun.util.calendar.ZoneInfo

Recently there is a process we’re working on taking a lot more memory than expected. Upon checking the heap there are a lot of java.util.LocalTime created. Which can be explained because we do store some data in a timemap with LocalTime as key. Probably there is too much of that data generated from upstream compared to the expected.
However, there is a surprise that also a lot of sun.util.calendar.ZoneInfo are created. We don't use this class; will it generated by LocalTime? But if we check the source code of java.time.LocalTime, I don't see ZoneInfo is used; does anyone have an idea about that?
Sorry for late answer but now I have found some time to inspect the JDK-sources.
If you call LocalTime.now() then java.time will use the system timezone (an implicit dependency).
public static LocalTime now() {
return now(Clock.systemDefaultZone());
}
And then Clock loads ZoneId.systemDefault():
public static Clock systemDefaultZone() {
return new SystemClock(ZoneId.systemDefault());
}
Finally, the class java.util.TimeZone is used to find the default zone.
public static ZoneId systemDefault() {
return TimeZone.getDefault().toZoneId();
}
And if you look into the source of TimeZone.getDefault() then you will see at some depth down the stack:
private static TimeZone getTimeZone(String ID, boolean fallback) {
TimeZone tz = ZoneInfo.getTimeZone(ID);
if (tz == null) {
tz = parseCustomTimeZone(ID);
if (tz == null && fallback) {
tz = new ZoneInfo(GMT_ID, 0);
}
}
return tz;
}
Voilá, the class sun.util.calendar.ZoneInfo will be loaded, too.

Store a local year for Date

I am going to store only year value in Database and retrieve it.
This is my domain (POJO)
#Entity
public class Publisher {
public Publisher(..., Date establishDate) {
//assign other variables
this.setEstablishDate(establishDate);
}
#NotNull
private Date establishDate;
...
}
And here is my DTO:
#NotNull
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy")
private Long establish_date;
Here, i am creating a new publisher:
new Publisher(..., new Date(this.establish_date));
I sent a json with value 1370 for establish_date (for post a new publisher) , but in Database it displays as: 1970-01-01 03:30:01
Why?
And when i Get the Publisher, it displays establish_date as 1000 !
What is wrong ?
You are using the wrong constructor. The argument specifies the milliseconds since 1970 - not a year: Date(long) You may use the right constructor: Date(int, int, int)
Note that most of the Date API is deprecated. There are better alternatives like Calendar and DateTime. Since you are only storing the year you could also use plain integer. This will make a lot easier.

How to setup jadira PersistentLocalDateTime with java.time.LocalDateTime?

I am trying to persist java.time.LocalDateTime using Hibernate and JPA. I used Jadira Framework ("org.jadira.usertype:usertype.core:3.2.0.GA" & "org.jadira.usertype:usertype.extended:3.2.0.GA"). I created package-info.java file and created #TypeDefs({#TypeDef(defaultForType = java.time.LocalDateTime.class, typeClass = org.jadira.usertype.dateandtime.threeten.PersistentLocalDateTime.class)}) there. I tested the solution and the java.time.LocalDateTime fields are stored/retrieved to my MySQL database in DATETIME columns (almost) correctly.
The only problem is that the values in database are +2 hours to the correct time value from fields in Java. I'm in CEST (UTC+2) so I understood that this is some problem with time zones. I debugged the code of PersistentLocalDateTime and this is what I found.
PersistentLocalDateTime is using org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper
AbstractTimestampThreeTenColumnMapper has field ZoneOffset databaseZone by default set to ZoneOffset.of("Z") (UTC).
Because it is thinking that my database is in UTC timezone (and the application is in UTC+2) it adds two hours to my time during conversion to database (and subtracts two hours from my time during conversion from database). So in the application I see the correct date and time but in database I not.
I found that a can add parameters to the #TypeDef so I specified them as below:
#TypeDef(defaultForType = LocalDateTime.class, typeClass = PersistentLocalDateTime.class,
parameters = {
#Parameter(name = "databaseZone", value = "+02:00")
}),
but I've got an exception:
java.lang.IllegalStateException: Could not map Zone +02:00 to Calendar
at org.jadira.usertype.dateandtime.threeten.columnmapper.AbstractTimestampThreeTenColumnMapper.getHibernateType(AbstractTimestampThreeTenColumnMapper.java:59)
I debugged a little bit more. AbstractTimestampThreeTenColumnMapper has two methods:
public final DstSafeTimestampType getHibernateType() {
if (databaseZone == null) {
return DstSafeTimestampType.INSTANCE;
}
Calendar cal = resolveCalendar(databaseZone);
if (cal == null) {
throw new IllegalStateException("Could not map Zone " + databaseZone + " to Calendar");
}
return new DstSafeTimestampType(cal);
}
private Calendar resolveCalendar(ZoneOffset databaseZone) {
String id = databaseZone.getId();
if (Arrays.binarySearch(TimeZone.getAvailableIDs(), id) != -1) {
return Calendar.getInstance(TimeZone.getTimeZone(id));
} else {
return null;
}
}
getHibernateType method throws the exception because resolveCalendar method returns null. Why it returns null? Because time zones IDs from java.time.ZoneOffset and java.util.TimeZone does not match. As far as I see the only possible value which match is Z. Any other values causes exceptions.
Is there any way to setup this correctly? Or is it a bug in the Jadira Framework?
It looks like a serious bug. The problem is that jadira.usertype.databaseZone parameter is parsed to ZoneOffset instead ZoneId. This way, resolveCalendar method compares 2 different types Zone and Offset. What is funny, parameter is named databaseZone but it does not contain zone. It contains only offset.
https://github.com/JadiraOrg/jadira/issues/42
https://github.com/JadiraOrg/jadira/issues/43

Java Date instances issue

I got the following in the body of the code:
public String getStartDate() {
return (new SimpleDateFormat("dd/MM/yyyy").format(startDate));
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
and startDate is initiated as Date startDate;
When I use the set startdate method, I am setting the value of this instance to the value of the object retrieved from database..
setStartDate(rsvIns.startDate);
Now the problem is here when I try to see if the startDate is equal to TodayDate,
Date todayDate = new Date();
if(startDate.equals(todayDate))
{
changeStatus(requestID, "Active");
}else{
//update status if others approved
changeStatus(requestID, "Approved");
}
I whenever it comes to the equals line it throws error and just doesn't execute the if or else part, hence the statement is never executed. Any idea why this could be happening?
Thanks,
I see 2 problems from the code snippets you provided:
Date todayDate = new Date() object contains in information on Hour, Minutes, Seconds and Milliseconds. If you compare it to a date created from a "dd/MM/yyyy" string you will have a problem caused by the time component of the Date object.
getStartDate() returns a String object. If that value is assigned to the startDate variable from the if statement, then on equals() call with a Date object parameter value the result will be false regardless of the startDate and parameter value, because the classes do not match.
If you get into situations like this and you do not see the answer, copy the code into a small program and debug trace it, look at the values of the objects. Trace into java code.
I have seen many times java developers with years of experience trip on the time component of Date object. They even clear the Hour, Minutes and Seconds and forget about the Milliseconds component.

Categories