BeGood
BeGood

Reputation: 191

How to get 7 bytes length only DES key

{
 KeyGenerator keyGen = KeyGenerator.getInstance("DES");
 SecretKey myKey = keyGen.generateKey();
 byte[] data = myKey.getEncoded();
 String encodedKey;
 encodedKey = Base64.getEncoder().encodeToString(data);
 System.out.println("My key1 :" +myKey);
 System.out.println("My key2 :" +encodedKey);
 System.out.println("My key3 :" +data);
}

it returns

My key1 :com.sun.crypto.provider.DESKey@fffe79f6  
My key2 :dg61j8hRCNY=   
My key3 :[B@2ac1fdc4

Could u guys tell me how do i get 7 bytes KEY , no more KEY PREFIX com.sun.crypto.provider.DESKey

Because i want to save my 7 chars ASCII into a file to HIDE it somewhere in the planet.

Upvotes: 2

Views: 413

Answers (2)

Holger
Holger

Reputation: 298103

You have different issues here.

  1. The key returned by DES has eight bytes because it has one parity bit per byte
  2. The conversion to ASCII using Base64 needs more characters than source bytes as it only uses five bits per character
  3. ASCII itself uses only seven bits per character so even if you convert directly to ASCII using all possible characters instead of only 64, you will need eight bytes

If you don’t want to store the parity bit, you can drop it as follows:

static byte[] dropParity(byte[] desKey) {
    if(desKey.length!=8) throw new IllegalArgumentException();
    BitSet in=BitSet.valueOf(desKey);
    BitSet out=new BitSet(56);
    for(int byteIndex=0, inIndex=0, outIndex=0; byteIndex<8; byteIndex++, inIndex++)
      for(int bitIndex=0; bitIndex<7; bitIndex++) out.set(outIndex++, in.get(inIndex++));
    byte[] byteArray = out.toByteArray();
    if(byteArray.length<7) // last byte(s) are zero
      byteArray=Arrays.copyOf(byteArray, 7);
    return byteArray;
}
static byte[] regenerateParity(byte[] desKey) {
    if(desKey.length!=7) throw new IllegalArgumentException();
    BitSet in=BitSet.valueOf(desKey);
    BitSet out=new BitSet(64);
    for(int byteIndex=0, inIndex=0, outIndex=0; byteIndex<8; byteIndex++)
    {
      boolean even=true;
      for(int bitIndex=0; bitIndex<7; bitIndex++) {
        final boolean bit = in.get(inIndex++);
        out.set(outIndex++, bit);
        even ^= bit;
      }
      out.set(outIndex++, even);
    }
    return out.toByteArray();
}

These two methods allow to convert the eight byte array to a seven byte array and back by dropping and regenerating the parity bit. Keep in mind that these bytes are not ASCII characters.


If you want to transfer a key through a channel which only accepts ASCII characters, you may use a direct encoding which uses seven bits per character. As said, that will still occupy eight bytes per key.

static String dropParityAndConvertToASCII(byte[] desKey) {
    if(desKey.length!=8) throw new IllegalArgumentException();
    char[] ch=new char[8];
    for(int i=0; i<8; i++) ch[i]=(char)((desKey[i]>>1)&0x7F);
    return new String(ch);
}
static byte[] convertFromASCIIAndAddParityBit(String desKey) {
    if(desKey.length()!=8) throw new IllegalArgumentException();
    byte[] ba=new byte[8];
    for(int i = 0; i < 8; i++) {
        int b = desKey.charAt(i)<<1;
        ba[i] = (byte)(b | Integer.bitCount(b)&1^1);
    }
    return ba;
}

The obstacle here is that the parity bit is the lowest bit while the unused bit of the ASCII encoding is the highest. So the key bytes are shifted by one bit and the highest bit set to zero to create ASCII bytes. When converting back, the value are shifted back and the parity bit is recalculated.

But note that not all ASCII characters are printable characters. If you want an encoding that is displayable, you have to resort to an encoding like Base64 and live with the fact that it produces more characters than key bytes.

Upvotes: 1

Derek Fung
Derek Fung

Reputation: 8211

The byte array data is the key you are asking for.

However, it is NOT in ASCII.

If you want to save it as text (ASCII), that's why you have to use an encoded format, e.g. using base64, like your encodedKey.

You can read it back later, and base64 decode it and get back the 7 byte key data.

Upvotes: 1

Related Questions