Das Problem liegt am arrayindex. Du beginnst die Index zähler bei 0 und ziehst dann für den Array zugriff 1 ab, macht einen index von -1, was natürlich nicht funktioniert.
Statt badchar = true kannst du auch continue; verwenden. Damit wir die schleife automatisch auf den nächsten Durchlauf gesetzt.
Die abbruchbedingung der For-schleife mit j < badchars.length || badchar == false ist auch eher fragwürdig, da jeder bad character dann nur einmal ersetzt würde. (im Fall von Hallo dann nur ein l)
Für einen vorzeitigen Schleifenabbruch bietet sich break; an. Damit wird die schleife beendet.
Ne foreach schleife wäre ev. auch einfacher
foreach(char c in myinputstirng)
{
}
Damit läuft die schleife durch alle Buchstaben ohne zutun
mit break und continue kann man das dann schön steuern.
wenns nicht klar is, schick ne PM